2009-06-25 62 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框架。当然,有些方法可以将它抽象出来,但是您仍然有遍布整个类的代码来检索依赖关系。由于所有优秀的框架都可以通过查看构造函数来找出需要的依赖关系,因此浪费了大量的工作和重复的代码。