2010-08-04 72 views
4

我有一個接口作爲構造函數參數的類。這個接口有兩個實現,我想根據變量來決定在運行時使用什麼實現。Autofac - 動態解析組件參數

問題是,上面的類是深入的對象heirarchy由Autofac解決,所以我不能傳遞參數。

像下面這樣的興趣是我想要實現的。

public interface IInterface1 {} 
public interface IInterface2 {} 

public class Class1 : IInterface2 
{ 
    public Class1(IInterface1 interface1) 
    { 
    } 
} 

public class Class2 
{ 
    public Class2(IInterface2 interface2) 
    { 
    } 
} 

public class Class3 
{ 
    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     // want to change which implementation of IInterface1 is resolved based on the interface1ImplementationToChoose variable 
     var class2 = container.Resolve<Class2>(); 
    } 
} 

任何想法?

UPDATE:

爲了澄清,這是用於由工作正常現有應用程序的現有對象分層結構。而且,對象模型比本例中顯示的要大得多。因此,我並不想將工廠傳遞給對象圖中的每個構造函數,以供圖中深層的類使用。

有沒有辦法讓IInterface1的不同實現傳入Class1,而Class2不知道任何事情呢?

感謝

+0

你說「這個接口有兩種實現..」,但你的示例並沒有很好地顯示出來。你能否詳細說明,然後我會相應地更新我的答案。 – 2010-08-05 10:25:27

回答

6

是,注入一個工廠,隱藏了怎樣的類型選擇:

public class Class3 
{ 
    private Func<string, Class2> _class2Factory; 
    public Class3(Func<string, Class2> class2Factory) 
    { 
     _class2Factory = class2Factory; 
    } 

    public void GetClass2Instance(string interface1ImplementationToChoose) 
    { 
     var class2 = _class2Factory(interface1ImplementationToChoose); 
    } 
} 

然後在容器設置,東西沿着這些線路:

builder.RegisterType<Implementation1>().Named("imp1").As<IInterface1>(); 
builder.RegisterType<Implementation2>().Named("imp2").As<IInterface1>(); 
builder.Register<Func<string, Class2>>(c => 
    { 
     var context = c.Resolve<IComponentContext>(); 
     return imp => new Class2(context.Resolve<IInterface1>(imp)); 
    }); 
builder.RegisterType<Class3>(); 

您現在可以使用Class3這樣的:

public class Class4 
{ 
    public Class4(Class3 class3) 
    { 
     var class2with1 = class3.GetClass2Instance("imp1"); 
     var class2with2 = class3.GetClass2Instance("imp2"); 
    } 
} 

注意:我假設你的意思是Class2應注入不同的實現相同的接口IInterface1。你的示例有點混亂,因爲你顯示了兩個實現不同接口的類。

+0

看起來不錯;另外,c =>新的Class2(context.Resolve (imp))就足夠了(除非你打算保留一個引用,否則你不需要明確地解析IComponentContext。) – 2010-08-05 22:30:45

+0

我不僅在'Class2' ,在這種情況下,我正在註冊一個'Func '委託,它必須攜帶它自己的上下文。對? – 2010-08-06 08:14:47

+0

@Nicholas - 我忘記了我應該爲註冊調用指定委託類型,或許現在更有意義。我仍然覺得我不得不解決一個新的上下文來在lambda中「存儲」... – 2010-08-06 10:02:41