【问题标题】:Different ways to inject dependencies in ASP.NET MVC Controllers?在 ASP.NET MVC 控制器中注入依赖项的不同方法?
【发布时间】:2009-06-25 14:54:51
【问题描述】:

在我在网上看到的大多数示例中,MVC 控制器中的 DI 都是这样完成的

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

使用了自定义 ControllerFactory,它利用了所选的 DI 框架并注入了存储库。

为什么以上被认为优于

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

这将获得相同的结果,但不需要自定义控制器工厂。

就测试而言,Test App 可以有一个单独的 BootStrapper。这样,当控制器被测试时,他们可以得到假的存储库,当它们被真正使用时,他们会得到真实的。

【问题讨论】:

    标签: asp.net-mvc dependency-injection structuremap


    【解决方案1】:

    构造函数注入(第一种方法)优于服务定位器模式(第二种方法)有几个原因。

    首先,服务定位器隐藏了依赖关系。在您的第二个示例中,仅查看公共接口,无法知道 ProductControllers 需要存储库。

    更重要的是,我必须回显OdeToCode。我觉得

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

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

    尤其是在测试夹具的SetUp 方法中配置了 ObjectFactory。

    最后,服务定位器模式在至少一种特定情况下显然是次优的:当您编写的代码将被编写您无法控制的应用程序的人使用时。我打赌人们通常更喜欢构造函数注入(或其他 DI 方法之一),因为它适用于所有场景。为什么不使用涵盖所有情况的方法?

    (Martin Fowler 在"Inversion of Control Containers and the Dependency Injection Pattern" 中提供了更彻底的分析,尤其是“服务定位器与依赖注入”部分)。

    【讨论】:

      【解决方案2】:

      第二个构造函数的主要缺点是现在必须为每个测试正确配置 IoC 容器。随着代码库的增长和测试场景的多样化,这种设置可能会成为真正的负担。当您明确地通过测试替身时,测试通常更易于阅读和维护。

      另一个问题是将大量类耦合到特定的 DI/IoC 框架。当然,有一些方法可以将其抽象出来,但是您仍然在整个类中散布代码来检索依赖项。由于所有好的框架都可以通过查看构造函数来确定您需要哪些依赖项,因此这是浪费大量精力和重复代码。

      【讨论】:

        【解决方案3】:

        当你使用第二种方法时,缺点是:

        • 需要大量不可读的测试设置/上下文方法
        • 容器与控制器耦合
        • 您将需要编写更多代码

        当你不想依赖注入时,为什么还要使用 ioc 容器?

        【讨论】:

          猜你喜欢
          • 2015-12-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多