2016-07-21 10 views
0

Ich habe zwei Schnittstellen ILogger und ILogger<T>, letztere erbt von der ehemaligen. Und einige Klasse Handler mag:Autofac mit generischen Objekten als nicht-generische Parameter

public class Handler 
{ 
    public Handler(ILogger logger) 
    { 
    } 
} 

und ich möchte Autofac sagen, zu lösen und gehen in einem ILogger<T> anstelle eines ILogger. Angenommen, ich kann Instanzen von ILogger und ILogger<T> auflösen, so dass das hier nicht das Problem ist.

Ich weiß, ich könnte eine Instanz übergeben, indem Sie:

builder.RegisterType<Handler>() 
     .AsSelf() // assume any other suplerfluos config is also done 
     .WithParameter(...); 

Es 3 Überlastungen (zumindest auf meiner Version von Autofac), aber alle drei von ihnen irgendwie eine Instanz als Parameter implizieren verwenden.

würde Ich mag, wie etwas tun: .WithParameter(typeOf(ILogger<Handler>))

Gibt es eine Möglichkeit, dies zu tun?

+0

Wie würden Sie davon ausgehen, dass dies zur Laufzeit funktioniert? Sie könnten sicherlich nicht so etwas schreiben, das kompilieren würde. Warum sollten Sie erwarten, dass sich die Laufzeit anders verhält? –

+0

Wenn ich manuell eine Handler-Instanz erstellen müsste, könnte ich 'var handler = new Handler (new DefaultLogger ());' und es würde funktionieren. Ich dachte, es gibt einen Weg, Autofac das für mich zu tun, wenn ich nach einem Handler frage. – Luiso

+0

Warum ordnen Sie 'ILogger' nicht einfach' DefaultLogger () 'zu? Oder wäre es 'DefaultLogger ()' für den 'ILogger', der in' Handler2' injiziert werden muss? –

Antwort

1

Dies kann mithilfe von Registrierungsereignissen geschehen.

/// <summary> 
/// DI registrations for loggers. 
/// </summary> 
public class LoggersModule : IModule 
{ 
    public void Configure(IComponentRegistry componentRegistry) 
    { 
     componentRegistry.Registered += (sender, e) => 
           e.ComponentRegistration.Preparing += OnComponentPreparing; 
    } 

    private static void OnComponentPreparing(object sender, PreparingEventArgs e) 
    { 
     var t = e.Component.Activator.LimitType; 
     e.Parameters = e.Parameters.Union(new[] 
     { 
      new ResolvedParameter(
               (p, i) => p.ParameterType == typeof(ILogger), 
               (p, i) => LoggerFactory.GetLoggerForClass(t)) 
     }); 
    } 
} 

Wo LoggerFactory.GetLoggerForClass() im Wesentlichen eine Instanz von ILogger<T> schafft.