2017-05-03 11 views
1

私はILoggerFactoryの実装をAutofacコンテナに登録しました。私はAutofacで次のクラスを登録し、それをインスタンス化することができることができるようにしたい:私は任意のクラスTためILogger<T>の実装のインスタンスを生成するために「教える」Autofacにできるようにする必要があり、そのためにAutofacと汎用インターフェースの工場

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

。必要なタイプのインスタンスを生成することができるILoggerFactory拡張メソッドCreateLogger<T>()CreateLogger(Type)がありますが、それらを呼び出すためにAutofacを作成する方法については私の頭を覆すことはできません。

私は非ジェネリック​​を望んでいた場合、私は

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

を書くと思いますが、私は一般的なもののために何をすべきかわかりません。すべてのポインタ?

更新は:

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>(); 

作品documentationいくつかのより多くを読んだ後、私はこれを思い付きました。問題はどのように動作するのか(さらに重要なのはどのように壊れる可能性があるか)を完全には理解できないため、私はまだより洗練された解決策を探しています。

+0

WICHにコードの一部は、あなたが理解していませんか? –

+0

どのようなパラメータがどのように働いているのかわかりません。 – n0rd

答えて

1

私はだけILogger<T>ためMicrosoft.Extensions.Loggingパッケージから、単純な答えを見つけた:Microsoft.Extensions.DependencyInjectionパッケージからServiceCollectionを使用して:

 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>(); 
関連する問題