2010-01-29 54 views
33

我正在使用Unity IoC容器來解析我的對象。但是,我遇到了一個問題。當我有多個構造函數時 - Unity如何知道使用哪一個?當我有一個和一個沒有時,它似乎使用帶參數的那個。我可以明確告訴它使用哪個構造函數嗎?指定Unity IoC容器使用的構造函數

具體來說,我有一個情況類似於下面的人類有兩個構造函數。在這種情況下,我希望IoC容器使用默認構造函數 - 不帶參數 - 但它選擇帶參數的構造函數。

public class SomeValueObject 
{ 
    public SomeValueObject(string name) 
    { 
     Name = name; 
    } 
    public string Name { get; set; } 
} 

public class Person 
{ 
    private string _name; 

    public Person() 
    { 
     _name = string.Empty; 
    } 

    public Person(SomeValueObject obj) 
    { 
     _name = obj.Name; 
    } 
} 

這顯然失敗了,因爲它不能創建SomeValueObject - 不知道要注入到它的字符串參數。它給出的錯誤是:

解析依賴失敗,type =「MyApp.Person」,name =「」。異常消息是:當前構建操作(構建鍵構建鍵[MyApp.Person,null])失敗:嘗試調用構造函數MyApp.Person(MyApp.SomeValueObject obj)時無法解析參數obj。 (策略類型BuildPlanStrategy,指數3)

容器登記:

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager()); 

而解決:

var person = Container.Resolve<Person>(); 
+0

是不是IoC的使用接口? – Martin 2010-01-29 13:10:44

+3

當然,我主要是這麼做的。但是這對問題沒有影響。 – stiank81 2010-01-29 13:13:02

+0

@Martin許多程序員使用類並避免了製作接口的假通用性,然後只實現了它。它還可以避免在大多數企業應用程序中看到大量臭臭的IoC接線,但仍可以在需要時切換某些實施。 http://programmers.stackexchange.com/questions/133471/writing-testable-code-vs-avoiding-speculative-generality – 2015-12-14 11:57:38

回答

46

註冊像這樣代替:

container.RegisterType<Person>(new InjectionConstructor()); 

您可以添加LifetimeManager以及使用RegisterType方法的重載。

也就是說,當爲DI建模時,如果您有明確的構造函數(即沒有重載的構造函數),您的生活會容易得多。

+0

你引用了哪些重載? – Casey 2014-03-25 15:17:21

+0

@Casey ...我相信空的構造函數。 – granadaCoder 2015-11-02 20:12:17

+0

由於沒有針對InjectionConstructor的參數,它正在調用Person的空構造函數。如果代碼是'新的InjectionConstructor(新的SomeValueObject(「John Smith」))',那就會調用(其他)Person構造函數,其中「other」構造函數是使用SomeValueObject對象/參數的構造函數。 – granadaCoder 2016-09-13 20:49:29

4

Multiple-Constructor Injection Using an Attribute

當目標類包含多於 一個構造函數w第i個參數相同數量的 ,必須應用 InjectionConstructor屬性到 構造的統一容器 將用來指示容器應使用哪個構造 。如同 自動構造注射,你可以 指定構造參數 作爲具體類型,或可以指定 爲其 統一容器包含 註冊映射的接口或基類。

22

默認情況下,Unity選擇具有最大參數個數的構造函數。爲了覆蓋這個,用InjectionConstructorAttribute修飾所需的構造函數。

+4

我們應該提到裝飾構造函數將組件連接到Unity作爲它的IoC容器。在註冊期間處理規範可能更可取,因此組件不需要參考Unity,因此如果需要,可以將不同的IoC交換出去。 – 2016-03-08 22:11:42

0

我真的必須指出在這種情況下使用依賴注入的方式是錯誤的。容器應該能夠在構造上注入SomeValueObject。

你最可能應該做的是註冊SomeValueObject的默認對象。而名稱屬性返回string.Empty

+0

也許我的簡單例子是有點關閉,但實際代碼中需要兩個不同的構造函數..謝謝你提到。 – stiank81 2010-01-29 18:17:50

+0

如果你還沒有寫過它? – Casey 2014-03-25 15:06:11

相關問題