2013-03-14 3 views
15

Ich versuche, das Delegierten Fabrikmuster mit Autofac zu verstehen. Ich weiß, wie Fabrik zur Umsetzung mit iIndex <> mit Keyed() Registrierung, die in hier schön erklärt: Configuring an Autofac delegate factory that's defined on an abstract classAutofac Delegat Fabrik mit Funk <>

Ich mag würde wissen, ob ich eine Fabrik mit Func erstellen <>, und wie würde ich das tun Anmeldungen für das folgende Beispiel:

public enum Service 
{ 
    Foo, 
    Bar 
} 

public interface FooService : IService 
{ 
    ServiceMethod(); 
} 

public interface BarService : IService 
{ 
    ServiceMethod(); 
} 

public class FooBarClient 
{ 
    private readonly IService service; 

    public FooBarClient(Func<Service, IService> service) 
    { 
     this.service = service(Service.Foo); 
    } 

    public void Process() 
    { 
     service.ServiceMethod(); // call the foo service. 
    } 
} 
+0

Warum gehst du nicht einfach verwenden 'IIndex <>' mit 'Keyed()'? Autofac kann diesen 'Func ' nicht für Sie erstellen. Sie müssen es in Ihrem Container registrieren mit 'Keyed()' oder 'Named()' etwas wie: 'builder.Register > (c => s => c.ResolveKeyed (s)); 'Delegate Factories können nur einen Typ mit Parametern erstellen und keinen Typ basierend auf dem Parameter auswählen, da dies 'IIndex <>' für ist. – nemesv

+2

Für IIndex <> muss ich auf die Autofac-Bibliothek verweisen, die ich vermeiden möchte. Ich möchte, dass mein DI-Code nur dann in Composite Root (separate Bibliothek) ist, wenn es möglich ist. –

Antwort

16

Autofac kann diese Func<Service, IService> für Sie nicht konstruieren, welche können Sie verschiedene Arten Rückkehr auf einem Parameter basiert. Dies ist, was IIndex<> ist für.

Allerdings, wenn Sie nicht wollen/können nicht IIndex<> verwenden Sie können diese Fabrik-Funktion mit Hilfe des Keyed oder Named erstellen und die Fabrik im Container registrieren:

var builder = new ContainerBuilder(); 
builder.RegisterType<FooBarClient>().AsSelf(); 
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo); 
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar); 

builder.Register<Func<Service, IService>>(c => 
{ 
    var context = c.Resolve<IComponentContext>(); 
    return s => context.ResolveKeyed<IService>(s); 
}); 
+0

danke nemesv! es funktioniert wie erwartet !!! Just one Frage, wird es einen Unterschied in der Leistung geben - IIndex vs Func? –

+0

Ich weiß nicht, wie IIndex implementiert ist und welche Art von Chaching oder Leistungsoptimierung es hat. Sie können die Implantation überprüfen oder Sie müssen für Ihr Szenario maßgeschneiderte Leistungstests durchführen, um die beiden zu vergleichen. – nemesv

+2

Ich habe gerade versucht, dass mit der Grundversion, aber es gibt mir eine 'ObjectDisposedException' ... Ich" gelöst "dies durch Aufruf von' New Foo' innerhalb der Delegierten (was ein biiiig Nogo ist!) –

Verwandte Themen