2010-09-15 17 views
9

我想注入依賴於我的MVC控制器這樣統一框架IoC和默認構造函數

private static void RegisterContainer(IUnityContainer container) 
{    
    container 
     .RegisterType<IUserService, UserService>() 
     .RegisterType<IFacebookService, FacebookService>(); 
} 

的UserService類有這樣的構造......

public UserService(): this(new UserRepository(), new FacebookService()) 
{ 
    //this a parameterless constructor... why doesnt it get picked up by unity? 
} 

public UserService(IUserRepository repository, IFacebookService facebook_service) 
{ 
    Repository=repository; 
    this.FacebookService=facebook_service; 
} 

異常我得到的是以下...

當前類型, Repositories.IUserRepository, 是一個接口,不能被 構建。您是否缺少映射類型 ?

它看起來像試圖注入一個構造函數到服務,但默認就足夠了?爲什麼它沒有映射到無參數的構造函數?

+0

什麼是'Repository'和'this.FacebookService'? – SwDevMan81 2010-09-15 03:22:56

回答

25

Unity默認約定(在文檔中明確指出)是選擇參數最多的構造函數。你不能只是簡單地聲明「IoC不會找到最具體的構造函數,如果你在註冊類型時沒有指定構造函數參數,它會自動調用默認構造函數。」每個容器實現可以並且確實具有不同的默認值。

在Unity的情況下,就像我說的那樣,它會選擇參數最多的構造函數。如果有兩個參數最多的話,那麼它會變得模棱兩可並且拋出。如果你想要不同的東西,你必須配置容器來做到這一點。

你的選擇是:

放在你想叫構造函數[InjectionConstructor]屬性(不推薦,但快速和容易)。

使用API​​:

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

使用XML配置:

<container> 
    <register type="UserService"> 
    <constructor /> 
    </register> 
</container> 
+0

溫莎城堡選擇了最匹配的構造函數,而Unity仍然不能。 – 2015-08-08 21:18:12

+0

這是一個故意的折衷。 Unity可以解決沒有在容器中註冊的具體類型,Windsor無法知道。這使得「最佳匹配」確實含糊不清,所以我們採用了更確定的默認值。 – 2015-08-08 23:04:11

+1

感謝您的澄清。我看到我的評論包含不必要的強烈論據。這應該是「單位不自動選擇構造函數」而不是「不能」:)看起來他們選擇了其他路徑設計決策以及http://stackoverflow.com/a/499675/929902無論如何,我很高興與統一和與它的靈活性。 – 2015-08-09 02:03:10

0

我無法專門針對Unity,但IoC容器通常會嘗試使用他們可以找到的最具體的構造函數,因爲它是構造函數

如果有一個構造函數需要兩個注入依賴關係,那麼推測它們是使用該對象所必需的;如果容器調用它,默認的構造函數將不得不做一些事情來完成它們。容器的工作是完成依賴關係,那麼如果沒有指示讓它繼續上課,爲什麼還要讓班級這樣做呢?

爲了您的具體問題,根據您的代碼:

private static void RegisterContainer(IUnityContainer container) 
{    
    container 
     .RegisterType<IUserService, UserService>() 
     .RegisterType<IFacebookService, FacebookService>(); 
} 

IUserRepository未註冊。添加一條線如

.RegisterType<IUserRepository, UserRepository>() 
+0

IoC會找到最具體的構造函數,如果在註冊類型時沒有指定構造函數參數,它會自動調用默認構造函數。 – TalentTuner 2010-09-15 03:38:18

+0

我不知道你使用過哪些容器,但我幾乎從不在映射中指定構造函數。我確實知道StructureMap會更喜歡一個更完美的構造函數給默認構造函數 - 我在當前項目中使用它,這就是我如何測試一些必須具有默認構造函數的對象(例如WCF Services,例如)。我很確定溫莎城堡也會更喜歡更具體的構造函數。 – arootbeer 2010-09-15 03:42:44

+1

@saurabh在我的Unity經驗中,當沒有指定參數時,使用最具體的構造函數。 – 2010-09-15 03:54:38