2017-05-03 2 views
1

ILoggerFactory 구현이 Autofac 컨테이너에 등록되어 있습니다. 나는 Autofac 다음과 같은 클래스를 등록하고 인스턴스화 할 수 할 수 있도록하려면 : 그 내용은Autofac과 일반 인터페이스를위한 공장

public class Test 
{ 
    public Test(ILogger<Test> logger) 
    { 
     logger.LogInformation("Works!"); 
    } 
} 

내가 모든 클래스 T에 대한 ILogger<T>을 구현 인스턴스를 생성 할 '가르쳐'Autofac 할 수 있어야합니다. 필요한 형식의 인스턴스를 생성 할 수있는 ILoggerFactory 확장 메서드 CreateLogger<T>()CreateLogger(Type)이 있지만이를 호출하기 위해 Autofac을 만드는 방법에 대해 머리를 감쌀 수 없습니다. 내가 제네릭이 아닌 ILogger을 원한다면

, 나는

containerBuilder.Register(c => c.Resolve<ILoggerFactory>().CreateLogger("default")) 

쓰기 싶지만 나는 일반 사람을 위해 무엇을해야할지 모르겠어요. 어떤 포인터?

업데이트 : documentation 좀 더 읽은 후, 나는이 함께했다 : 다음

public class LoggingModule: Autofac.Module 
{ 
    private readonly MethodInfo mi; 

    public LoggingModule() 
    { 
     this.mi = typeof(LoggerFactoryExtensions) 
      .GetMethod(nameof(LoggerFactoryExtensions.CreateLogger), new[] { typeof(ILoggerFactory) }); 
    } 

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) 
    { 
     registration.Preparing += OnComponentPreparing; 
    } 

    private void OnComponentPreparing(object sender, PreparingEventArgs e) 
    { 
     e.Parameters = e.Parameters.Union(
      new[] 
      { 
       new ResolvedParameter(
        (p, i) => IsGenericLoggerParameter(p.ParameterType), 
        (p, i) => CreateLogger(this.mi, p.ParameterType, i.Resolve<ILoggerFactory>()) 
        ) 
      }); 
    } 

    private static bool IsGenericLoggerParameter(Type parameterType) 
    { 
     return parameterType.IsGenericType && parameterType.GetGenericTypeDefinition() == typeof(ILogger<>); 
    } 

    private static object CreateLogger(MethodInfo mi, Type typeArg, ILoggerFactory loggerFactory) 
    { 
     Type genericArg = typeArg.GetGenericArguments().First(); 
     MethodInfo generic = mi.MakeGenericMethod(new[] { genericArg }); 
     return generic.Invoke(null, new[] { loggerFactory }); 
    } 
} 

그리고 :

 containerBuilder.RegisterType<Test>().AsSelf(); 
     containerBuilder.RegisterModule<LoggingModule>(); 
     var container = containerBuilder.Build(); 
     var test = container.Resolve<Test>(); 

작품. 문제는 어떻게 작동하는지 (그리고 더 중요한 것은 어떻게 깨질 수 있는지) 완전히 이해하지 못하기 때문에 더 우아하고 이해하기 쉬운 솔루션을 찾고 있습니다. Microsoft.Extensions.DependencyInjection 패키지에서 ServiceCollection를 사용하여 :

+0

느릅 나무 부분은 당신이 이해하지 않는 ? –

+0

매개 변수가 무엇이며 어떻게 작동하는지 이해할 수 없습니다. – n0rd

답변

1

나는 그러나 단지 Microsoft.Extensions.Logging 패키지에서 ILogger<T>에 대한 간단한 답을 발견

 IServiceCollection services = new ServiceCollection(); 
     services.AddLogging(); // all the magic happens here 
     // set up other services 
     var builder = new ContainerBuilder(); 
     builder.Populate(services); // from the Autofac.Extensions.DependencyInjection package 
     IContainer container = builder.Build(); 
     Test t = container.Resolve<Test>(); 
코드의
관련 문제