2

最近我搬到了MVC 3和Ninject 2中。在大多數代碼中,我使用構造函數注入,但也有一些地方,我不得不使用Inject屬性。 Ninject 2註冊自己的IDepencyResolver接口。我不喜歡DependencyResolver類是System.Web.Mvc命名空間的一部分,因爲它的功能是不是真的嚴格把MVC,但是現在,當它是存在的,我能做到NInject和MVC 3 - 我應該使用DependencyResolver而不是[Inject]屬性嗎?

public SomeClass 
{ 
    public IUserService UserService { get; set; } 

    public SomeClass() 
    { 
     UserService = DependencyResolver.Current.GetService<IUserService>(); 

,而不是

public SomeClass 
{ 
    [Inject] 
    public IUserService UserService { get; set; } 

所以我不必在我的類中引用Ninject命名空間。應該如此使用DependencyResolver

回答

5

我使用屬性注入只適用於類的正常工作不需要的依賴關係,但如果用戶設置它們可以添加一些功能。這種功能的例子是日誌記錄。所以你可以有一個屬性,代表一個記錄器,用戶可以提供自己的實現,如果他不繼續正常工作,但它不會記錄。

對於其他所有我使用構造函數注入。通過這種方式,您可以向消費者指出此類對某些其他服務具有所需的依賴關係。

所以回答你關於該酒店注入我會質疑只是有:

public SomeClass 
{ 
    public IUserService UserService { get; set; } 

    public void SomeMethodWhichDoesntEnforceUserService() 
    { 
     if (UserService != null) 
     { 
      // Provide some additional functionality 
     } 
    } 
} 

,如果你的類不能未經用戶服務正常運行:

public SomeClass 
{ 
    private readonly IUserService _userService; 
    public SomeClass(IUserService userService) 
    { 
     _userService = userService; 
    } 

    public void SomeMethodWhichRequiresTheService() 
    { 
     _userService.DoSomething(); 
    } 
} 

因此,在這兩種情況下沒有參考到任何DI細節。這就是控制反轉的全部內容。

1

我想問的第一個問題是爲什麼你不能執行IUserService的構造函數注入到SomeClass?這可能表明設計存在問題。

爲避免直接引用DependencyResolver,您可以通過DI框架實現服務定位器的某種形式的抽象,例如, CommonServiceLocator,但正如對this question的回答所表明的,當正確地進行DI時,這樣的抽象不應該是必需的。相反,您應該調整應用程序的設計。

+0

`DependencyResolver`是對`DI`庫的某種抽象。這個類與Ninject無關。我在基類中使用`Inject`屬性,因爲我不想將參數添加到每個繼承類的構造函數中。我也有一些循環參考問題。 – LukLed 2011-02-16 17:56:32

+0

不好意思,我對ninject不太熟悉,但如果你關心ninject引用的污染代碼,自動構造函數注入不是一個選項嗎? http://kohari.org/2008/06/08/attributes-we-dont-need-no-stinkin-attributes/ – 2011-02-16 18:06:50

+0

構造函數注入是一個選項,但我不想擁有巨大的構造函數。好。當我沒有太多想法時,我可能會做太多的想法。 – LukLed 2011-02-16 18:34:22

0

我相信mvc3的ninject.web.mvc版本現在支持過濾器屬性上的構造函數注入。你試過了嗎?

相關問題