2010-03-18 62 views
31

給定一個具有幾個構造函數的類 - 我如何告訴Resolve使用哪個構造函數?Unity.Resolve如何知道使用哪個構造函數?

請看下面的例子類:

public class Foo 
{ 
    public Foo() { } 
    public Foo(IBar bar) 
    { 
     Bar = bar; 
    } 
    public Foo(string name, IBar bar) 
    { 
     Bar = bar; 
     Name = name; 
    } 
    public IBar Bar { get; set; }   
    public string Name { get; set; } 
} 

如果我想創建一個使用解決如何將解決知道要使用哪個構造Foo類型的對象?我怎麼能告訴它使用正確的?假設我有一個IBar註冊的容器 - 它是否會理解它應該支持使用IBar的構造函數?如果我也指定一個字符串 - 它會使用(string, IBar)構造函數嗎?

Foo foo = unityContainer.Resolve<Foo>(); 

並請忽略的事實,它可能會更容易,如果該類只是有一個構造函數...

回答

53

當目標類包含一個以上的構造函數,統一將使用一個應用了InjectionConstructor屬性。如果有多個構造函數,並且沒有一個攜帶InjectionConstructor屬性,那麼Unity將使用具有最多參數的構造函數。如果有多個這樣的構造函數(超過一個具有相同參數數量的「最長」),Unity將引發異常。

link text

+0

太好了。謝謝..! – stiank81 2010-03-18 13:44:36

+0

正是我在找的東西!我只是裝飾我想與[InjectionConstructor] – 2014-05-13 12:45:18

+2

一起使用的構造函數這就是爲了節省一個週末的答案。明確定義。 – 2014-10-19 17:53:58

28

當您註冊類型兩者,你可以指定這樣使用哪個構造函數:

container.RegisterType<Foo>(
    new InjectionConstructor(
     new ResolvedParameter<IBar>())); 

上面的代碼是從內存,但是這是基本原則。在這種情況下,我選擇了帶有IBar類型的單個參數的構造函數。

並請忽略的事實,它可能會更容易,如果該類只是有一個構造函數...

我不能忽視這一點。說到建築師注入,歧義是一種設計氣味。你基本上在說:我真的不知道我是否在意這種依賴性。

當然,Unity很可能會爲你弄明白,但是你會依賴特定的容器行爲而不是正確地設計你的API。 其他容器可能有不同的行爲,所以如果您選擇從Unity遷移到更好的容器,可能會出現細微的錯誤。

DI-friendly, but container-agnostic的方式編寫代碼要安全得多。

+0

謝謝!但是,我真的需要在容器中註冊類型嗎?我將使用容器來解析Foo的實例,但我不需要Foo來放在容器中。但我仍然應該使用RegisterType?或者僅僅因爲我有這個特定的需求來告訴它使用哪個構造函數? – stiank81 2010-03-18 14:17:41

+0

是的,沒有。正如ozczecho引用的那樣,Unity在面對不明確性時使用啓發式方法來選擇構造函數(它使用大多數參數選擇構造函數)。如果你需要它偏離這個算法,你必須明確地告訴它。一種方法是應用InjectionConstructor屬性,另一種方法是將其註冊到容器中。我個人更喜歡在容器中註冊類型,因爲這樣可以讓我的代碼保持與容器無關。如果適用,它還允許不同的容器配置。 – 2010-03-18 14:27:28

+0

FWIW,Unity即使尚未在容器中註冊,也能解決具體的類型,這是它的特色。有些容器支持該功能,而其他容器則不支持。 – 2010-03-18 14:35:36

相關問題