2009-06-25 87 views
4

在大多數的樣品我看到在網絡上,DI在MVC控制器可以是這樣在ASP.NET MVC控制器中注入依賴的不同方法?

public ProductController(IProductRepository Rep) 
{ 
    this._rep = Rep; 
} 

使用自定義的ControllerFactory完成,它利用選擇的DI框架和庫注入。

爲什麼上面的考慮優於

public ProuctController() 
{ 
    this._rep = ObjectFactory.GetInstance<IProductRepository>(); 
} 

這將得到相同的結果,但並不需要自定義控制器工廠。

就測試而言,測試應用程序可以有一個單獨的BootStrapper。通過這種方式,當控制器正在測試時,他們可以獲得虛假的存儲庫,當他們被使用時,他們會得到真正的存儲庫。

回答

5

基於以下原因,構造函數注入(第一種方法)比服務定位器模式(第二種方法)更好。

首先,服務定位器隱藏了依賴關係。在第二個示例中,單獨查看公共接口,無法知道ProductControllers需要存儲庫。

更重要的是,我必須回聲OdeToCode。我認爲

IProductRepository repository = Mockery.NewMock<IProductRepository>(); 
IProductController controller = new ProductController(repository); 

是清楚不過

ObjectFactory.SetFactory(IProductRepository, new MockRepositoryFactory()) 
IProductController controller = new ProductController(); 

特別是如果ObjectFactory的是在測試夾具的SetUp所述的配置方法。

最後,服務定位器模式在至少一個特定情況下顯然不是最優的:當您編寫的代碼將被在您的控制之外編寫應用程序的人員使用時。我認爲人們通常更喜歡構造函數注入(或其他DI方法之一),因爲它適用於所有場景。爲什麼不使用涵蓋所有情況的方法?

(Martin Fowler在"Inversion of Control Containers and the Dependency Injection Pattern"中提供了更徹底的分析,特別是「服務定位器vs依賴注入」部分)。

4

當您使用第二種方法,缺點是:需要

  • 巨大且無法讀取測試設置/上下文方法
  • 容器被耦合到控制器
  • 你需要寫很多更多代碼

無論如何,當你不想依賴注入時,你爲什麼要使用ioc容器?

5

第二個構造函數的主要缺點是現在您的IoC容器必須爲每個測試正確配置。隨着代碼量的增加以及測試場景變得更加多樣化,這種設置可能成爲真正的負擔。當您顯式傳遞測試雙精度時,測試通常更易於閱讀和維護。

另一個問題是將大量的類耦合到特定的DI/IoC框架。當然,有些方法可以將它抽象出來,但是您仍然有遍佈整個類的代碼來檢索依賴關係。由於所有優秀的框架都可以通過查看構造函數來找出需要的依賴關係,因此浪費了大量的工作和重複的代碼。