【问题标题】:IOC best practice: How to best manage dependency graph?IOC 最佳实践:如何最好地管理依赖图?
【发布时间】:2010-02-19 15:44:05
【问题描述】:

我正在做一个 MVC 项目,将结构图作为 IOC 容器。我们正在做 TDD,我想设置我的依赖项,以便它易于使用并易于测试。

我应该如何最好地为以下虚构的图解图设置依赖关系图?

  • 应用程序控制器
    • 控制器
      • 身份验证服务
        • 用户存储库

您是否在控制器上注入用户存储库,并在身份验证服务中进一步注入?如果图表更深怎么办 - 你会不会从控制器开始获得很多依赖关系?

如果你对你的应用控制器有依赖,你是否也将它注入到控制器上,然后在基础上注入?

如果我让容器解析图表中间某处的实例,我是否必须设置容器进行测试?这是一件好事还是最好避免?

还有其他我没看到的方法吗?

【问题讨论】:

    标签: .net dependency-injection inversion-of-control structuremap ioc-container


    【解决方案1】:

    您的依赖关系图看起来不错。如图所示,每个类只有一个依赖

    • ApplicationController 依赖于 Controller
    • 控制器依赖于 AuthenticationService
    • AuthenticationService 依赖于 UserRepository

    我意识到这是一个简化的视图,并且您的实际生产架构会复杂得多,但是 DI(尤其是构造函数注入)的好处在于它违反了Single Responsibility Principle 太明显了。

    当一个类开始获得过多的依赖时,这表明你应该refactor to an Aggregate Service

    最终的依赖图可能巨大,但每个类只依赖于几个抽象,所以从架构的角度来看,这不是问题。

    您永远不必解析图表中间的实例。解决是您do in the Composition Root 的事情,并且(理论上)只有一次。

    说到单元测试,你shouldn't have to use a DI Container at all

    【讨论】:

      【解决方案2】:

      不确定您的 applicationController 如何与您的控制器相关,但一般来说,您的控制器将依赖于您的服务,而您的服务将依赖于存储库。

      例如

      public MyXyzController
      {
        public MyXyzController(IAuthenticationService authenticationService){...}
      }
      
      public class AuthenticationService : IAuthenticationService
      {
        public AuthenticationService(IUserRepository userRepository){...}
      }
      

      这样,当你请求(即解析)控制器时,你的 IOC 容器会自动解析所有依赖项。

      【讨论】:

      • 然后我要设置容器进行测试吗?
      • 不,正如 Mark Seemann 所说,您在单元测试时根本不需要 IOC 容器。您一次只需测试一个组件并模拟或存根任何依赖项。您可以使用模拟框架(例如 Moq)将模拟注入到每个被测组件中,然后您可以验证是否正确调用了依赖项上的方法。
      猜你喜欢
      • 2015-07-29
      • 2022-08-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 2010-12-11
      • 2012-10-09
      相关资源
      最近更新 更多