2011-10-28 56 views
4

我有一個ASP.NET MVC 3應用程序,它使用Ninject.MVC3擴展在我的MVC應用程序中設置DI。也就是說,App_Start文件夾中有NinjectMVC3.cs文件,在該文件夾中定義了我的綁定。這適用於DI進入我的應用程序的控制器。在ASP.NET MVC 3應用程序的類庫中引用Ninject

除了ASP.NET MVC Web應用程序,我的解決方案還包含一個類庫項目,我們稱之爲MyProject.Core,它具有我的域模型,服務等。在那裏,我有一個名爲UserServices類,使用稱爲EmailServices服務,像這樣:

public class UserServices : IUserServices 
{   
    private readonly IEmailServices _emailServices = new EmailServices(); 

    public void CreateUser(...) 
    { 
     // Create user... 

     _emailServices.SendWelcomeEmail(newUser); 
    } 
} 

正如你所看到的,UserServices類對EmailServices硬編碼的依賴,但我想爲實現這一目標也要配置爲使用DI。也就是說,在我的ASP.NET MVC應用程序(或單元測試項目或任何地方)中,我希望能夠說「綁定IEmailServices以使用TestEmailServices」,並且UserServices類使用TestEmailServices而不是EmailServices

我該如何去做這件事?我希望能夠做這樣的事情:

public class UserServices : IUserServices 
{   
    private readonly IEmailServices _emailServices = kernel.Get<EmailServices>(); 

    ... 
} 

但我不知道在哪裏kernel是從哪兒來,在這種情況下。我在問什麼是有意義的,還是我在這裏咆哮錯誤的樹?

感謝

回答

4

你應該能夠與構造注入做到這一點,是這樣的:

private readonly IEmailServices _emailServices; 

public UserServices(IEmailServices emailServices) 
{ 
    _emailServices = emailServices; 
} 

服務注入到你的控制器應該由Ninject定製的控制器工廠,which'll使用配置的IoC容器自動處理解決當創建所述控制器,所述IUserServices對象這將反過來由容器被給予IEmailServices對象:

public class MyController : Controller 
{ 
    private readonly IUserServices _userServices; 

    public MyController(IUserServices userServices) 
    { 
     _userServices = userServices; 
    } 
} 

當您的單元測試,可以手動注入虛假或模擬電子郵件服務進入用戶服務。

+1

是的,這是答案。不要將Ninject內核用作服務定位器。不要將你的庫實現與Ninject耦合。讓它在主應用程序中構造整個對象樹。 – Aaronaught

+0

啊,我應該試試看! <拍額頭/> :-)謝謝 –

0

如果您正在使用MVC 3無論如何,如何與註冊Ninject內置DependencyResolver?

System.Web.Mvc.DependencyResolver.SetResolver(yourKernel); 

然後,你可以只使用

var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>(); 

在你需要它。我不知道如果SetResolver直接接受Ninject內核,或者你需要一個包裝類,但我會認爲這是最乾淨的解決方案。

+0

這會工作,但它仍然依賴於服務定位器反模式,並且在MVC中完全沒有必要,您可以在其中註冊Ninject作爲控制器工廠,並在其他地方使用普通構造器注入。更不用說,它將類庫耦合到'System.Web.Mvc',這看起來不正確... – Aaronaught

+0

@Aaronaught是和不。 MVC 3中的DependencyResolver處理所有事情(因此不再需要控制器工廠,如果DependencyResolver可以解決它,它會自動使用DI)。但是,可能會出現這樣的情況,它根本不是注入所有依賴項的選項(例如,,我有一個HtmlHelper,它使用一個服務來處理一些格式化的東西 - 這可以在控制器中完成並放在模型上,但這對於僅用於顯示功能的服務來說是過度的) –

+0

'DependencyResolver'實際上是一個服務定位器用一個新的名字。我真的看不出在內核本身上使用它有什麼好處......它只是另一層間接尋址?我不相信除了MVC內部的任何東西之外,還有合理的需求,但我想可能會有一些模糊的例子。 – Aaronaught

相關問題