2

我一直在阅读大量 DI 和 autofac 的示例代码。我注意到的一件事是许多人将接口和实现捆绑在同一个项目中。从设计的角度来看,我认为这是不正确的,所有接口都应该单独组装。所以我这样定义我的项目:

UI - Web App/Windows App/Both - Views - Models - Controllers/ ViewModels Business - Services/Processes - Interfaces - Model DataAccess - Repositories & UoW - Interfaces - Model

这样,我的业务服务仅引用 DataAccess 接口和模型,但独立于实际实现。同理,UI也只指业务接口和模型,有明确的分离。这也有助于我测试可以独立测试层的位置。

我的问题是 Autofac 模块声明。我需要设置我的构建以将实现复制到最终部署目录中。我的业务模块需要参考数据访问实现,UI需要访问业务模块。

  1. 我应该如何处理模块中的这种依赖链?
  2. 我应该在哪里放置模块类以及启动代码应该如何以最简单的方式发现所有模块?

我正在考虑 Autofac 的程序集扫描,但不确定这是否是唯一的选择。另请注意,我已经遵循命名约定,并且在大多数情况下,我不会编写单独的绑定。我在这里担心的是

  1. 由于引用接口的项目不知道实现,因此我无法在调用程序集中编写任何特定绑定,例如 UI 根程序集。
  2. 一些消息来源谈到保持程序集与任何 DI 实现无关,并为模块提供单独的程序集。这对所有类型的应用程序都是一个好方法吗?(例如,企业 LOB 应用程序或 Web 应用程序与分发给许多独立用户的 ISV 桌面应用程序)
4

1 回答 1

1

我的观点是,在单独的程序集中拥有接口和实现是过度的并且没有提供价值,因为您必须部署这两个程序集才能使您的项目工作。我喜欢参考 Paul Stovell 的这条推文,他在其中指出名称空间是关注单元,而程序集是部署单元。我发现这很能引起我的共鸣。

回到您的问题:归根结底,您的可执行项目(Web 应用程序或 Windows 应用程序)需要知道接口和实现。
我的意见是 Autofac 模块应该存在于顶级项目中,因此它应该引用所有必要的项目。我的理由是,除了定义服务注册之外,您还将定义每个服务注册的生命周期。该概念取决于使用您的依赖项的项目;Web 项目可能会根据 HTTP 请求注册一些服务,而 Windows 应用程序可能有不同的生命周期。

对我来说,模块非常适合将注册组合在一起,但这并不意味着它们需要与包含注册的服务位于同一个项目中。

于 2018-12-19T02:19:12.323 回答