2013-03-14 59 views
15

我想了解委托工厂模式与Autofac。我知道如何使用IIndex <>与健()注册,这是在这里很好地解释实施工厂:Configuring an Autofac delegate factory that's defined on an abstract classAutofac委托工厂使用func <>

我想知道如果我能创建使用Func键<>工厂,我会怎么做以下示例注册:

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

你为什么不只是使用'KeyIndex <>'带'Keyed()'? Autofac无法为你创建这个'Func '。您需要使用'Keyed()'或'Named()'类似以下方式将其注册到容器中:'builder.Register >(c => s => c.ResolveKeyed (s) );'委托工厂只能创建一个带参数的类型,而不能根据参数选择一个类型,因为这就是'IIndex <>'的用途。 – nemesv 2013-03-15 07:26:59

+2

对于IIndex <>我将需要引用我试图避免的Autofac库。我希望我的DI代码只能在可能的情况下在Composite根目录(单独的库)中。 – 2013-03-15 08:10:35

回答

16

Autofac不能构建这个Func<Service, IService>你,它可以让您返回基于一个参数不同的类型。这是IIndex<>的用途。

但是,如果你不想/不能使用IIndex<>您可以用KeyedNamed的帮助下创建这个工厂函数和容器注册工厂:

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

谢谢nemesv!它的工作如期!正确的一个问题,性能会有什么不同 - IIndex vs Func? – 2013-03-15 09:47:23

+0

我不知道IIndex是如何实现的,它有什么样的chaching或性能优化。您可以检查植入情况,或者需要针对您的情况量身打造性能测试,以比较两者。 – nemesv 2013-03-15 09:52:31

+2

我只是试图与原因版本,但它给了我一个'ObjectDisposedException' ...我通过调用委托内的'新Foo'解决了这个问题(这是一个biiiig nogo!) – 2015-06-02 13:34:06