2016-04-21 8 views
2

Mit Ninject kann ich so etwas tun:Zugriff auf Kontextinformationen während der Lambda-Registrierung in Autofac?

Bind<ILogger>().ToMethod(context => 
{ 
    // Get type info 
    var type = context.Request.Target.Member.DeclaringType; 
    var logger = new ConcreteLogger(type); 

    Kernel.Get<IFoo>().DoFoo(logger); 
    return logger; 
}); 

Wie kann ich dies tun, mit Autofac?

Dies ist der Code, den ich habe:

builder.Register(context => { 
     var type = ????? 
     var logger = new ConcreteLogger(type); 

     context.Resolve<IFoo>().DoSomething(logger); 
     return logger; 
}).As<ILogger>(); 

ich im Debugger sehen können, dass context tatsächlich von der Art ist, Autofac.Core.Resolving.InstanceLookup die ein Mitglied hat ComponentRegistration.Target aber das kann ich nicht zugreifen, da InstanceLookup eine interne Klasse ist.

Es scheint, kann ich dies tun, aber es gibt mir nicht die Typinformationen der Klasse, die diese injiziert Typ erfordert:

builder.Register(context => { 
    var lookup = c as IInstanceLookup; 
    var target = lookup.ComponentRegistration.Target as ComponentRegistration; 
    var logger = new ConcreteLogger(target.Activator.LimitType); 

     context.Resolve<IFoo>().DoSomething(logger); 
     return logger; 
}).As<ILogger>(); 
+2

vielleicht http://stackoverflow.com/questions/11691583/autofac-register-component-and-resolve-depending-on-resolving-parent kann helfen? –

Antwort

1

Was Sie brauchen, ist eine Komponente auf „Eltern Basis zu injizieren " Komponente. Mit Autofac registrieren Sie Komponenten und diese Komponenten wissen nicht, wer sie benötigt.

Übrigens können Sie tun, was Sie wollen, indem Sie ein benutzerdefiniertes Modul implementieren. Exemple:

public class TestModule : Module 
{ 
    protected override void AttachToComponentRegistration(
     IComponentRegistry componentRegistry, 
     IComponentRegistration registration) 
    { 
     registration.Preparing += (sender, e) => 
     { 
      Parameter parameter = new ResolvedParameter(
       (pi, c) => 
       { 
        return pi.ParameterType == typeof(ILogger); 
       }, (pi, c) => 
       { 
        var p = new TypedParameter(typeof(Type), 
               e.Component.Activator.LimitType); 
        return c.Resolve<ILogger>(p); 
       }); 

      e.Parameters = e.Parameters.Union(new Parameter[] { parameter }); 
     }; 
     base.AttachToComponentRegistration(componentRegistry, registration); 
    } 
} 

und das Modul wie folgt registrieren:

builder.RegisterModule<TestModule>(); 

diese Weise wird jedes Mal, wenn eine Komponente gelöst werden, wird es einen neuen Parameter hinzuzufügen, die Art zu wissen, ist konstruiert, um die ILogger Abhängigkeit zu schaffen .

Beachten Sie, dass Sie dabei möglicherweise captive dependency haben: eine Abhängigkeit, die für eine Komponente erstellt wurde, aber für eine andere verwendet wird. Dies kann passieren, wenn Ihre Registrierung einen anderen Gültigkeitsbereich hat, z. B. einen Singleton-Bereich.

+0

Danke, dieser Code ist tatsächlich in einem Modul enthalten (es wird von Ninject portiert, der auch ein NinjectModule gespeichert hat). Ich habe es anhand Ihrer Vorschläge herausgefunden. – ilitirit

Verwandte Themen