2013-03-14 57 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