Dependency injection 隔离分层应用中的DI

Dependency injection 隔离分层应用中的DI,dependency-injection,inversion-of-control,unity-container,compositionroot,Dependency Injection,Inversion Of Control,Unity Container,Compositionroot,假设我们有三层;用户界面、业务、数据。我们正在使用DI。我不希望从UI访问数据层 问题是关于数据层的DI注册。合成根在UI中,我不想在那个里引用任何数据。我找到了这个。据我所知,我们应该参考所有层,并认为它们是库而不是层。通过这种方式,我可以指定我的业务层使用数据层或任何我想要的东西。毕竟,这就是DI存在的原因 这是正确的,但有一个问题!我们不应该在UI上使用数据层。但一旦一个开发人员意外地从UI引用到数据,另一个开发人员则直接从数据层向UI类注入了一些东西。所以他跳过了我永远不想要的业务层

假设我们有三层;用户界面、业务、数据。我们正在使用DI。我不希望从UI访问数据层

问题是关于数据层的DI注册。合成根在UI中,我不想在那个里引用任何数据。我找到了这个。据我所知,我们应该参考所有层,并认为它们是库而不是层。通过这种方式,我可以指定我的业务层使用数据层或任何我想要的东西。毕竟,这就是DI存在的原因

这是正确的,但有一个问题!我们不应该在UI上使用数据层。但一旦一个开发人员意外地从UI引用到数据,另一个开发人员则直接从数据层向UI类注入了一些东西。所以他跳过了我永远不想要的业务层

我如何处理这种情况?我希望有一些限制,但另一方面我希望DI的灵活性

当然,有些人相信,我们可以有一个单独的库来进行依赖项注册


这里的最佳模式是什么?

您链接到的答案有两个答案,说明在同一程序集中具有合成根和UI层不是问题:

  • 您将逻辑层与物理边界混淆:程序集是部署单元,可以包含多个逻辑层。层甚至可以分布在部件上。想想这个问题。合成根目录可能与UI位于同一程序集中,但它不在UI层中,尽管合成根目录依赖于数据访问层,但UI层不依赖(尽管其程序集依赖于数据访问层)
  • 代码评审对于软件的质量和团队内的知识共享非常重要。如果您现在没有进行代码审查,那么您肯定应该开始进行代码审查。这些代码审查可以包括检查体系结构准则,例如您在问题中描述的规则
  • 虽然程序集分离为您提供了编译时支持,但编译器无法检查大多数体系结构规则。此外,当开发人员向DAL程序集添加引用时,编译器不会抱怨。开发人员总会找到打破规则的方法。同样,代码审查也很有帮助。此外,作为架构师,您可以开始使用诸如NDepend之类的工具来自动验证某些体系结构规则。但是当您应用构造函数注入时,也可以使用单元测试,因为可以通过简单地反映UI层中类型的构造函数来找到依赖项
但是如果您认为这是一个问题,为什么不在自己的程序集中移动UI层呢?启动程序集不需要UI层!如果创建Windows窗体应用程序,请将所有窗体移动到它们自己的程序集中。如果要创建ASP.NET MVC应用程序,请将控制器和视图移动到它们自己的程序集。根据您正在构建的应用程序类型,您必须应用某些技巧才能使其正常工作,但对于.NET中的大多数项目类型,这是可能的


真正的问题是,这值得麻烦吗?如果您希望这样做是为了避免不得不进行代码审查,那么您就是在愚弄自己

使用代码审查来验证其他开发人员没有做您的体系结构指南禁止的事情。当然,我们可以有一些工具来实现这一点,但是没有更好的方法吗?不仅仅是代码审查。我将服务层放在数据和UI之间的原因之一是,我希望能够物理上分离服务层和UI(通过将DI配置为使用服务代理,而不是UI层的程序集)。但是考虑到一个启动程序集,是的,这正是我所想的,用相同的基础结构支持WPF和ASP.MVC应用程序。现在我可以直接放置WPF UI而不是当前的ASP.MVC。请您详细解释一下如何分离启动程序集和UI?关于分离UI,您想知道什么?启动项目应该是什么类型的项目?(ASP.NET MVC、库等)如果编写ASP.NET MVC应用程序,那么启动项目必须是ASP.NET MVC应用程序,因为IIS需要启动此应用程序。在这种情况下,视图和控制器应该放在类库项目中。如我所提到的,您对依赖项解析器(或注册器)项目有什么想法?