3

我一直在研究如何设计一个 MVC 4 Web 解决方案,该解决方案遵循依赖倒置原则,并利用配置流畅的依赖注入 (DI) 容器(即编译时类型检查)。

ASP.NET MVC 4 依赖注入的许多示例我发现重点关注在 MVC 框架提供的入口点中实现 DI 的细节。我发现自己倾向于最终的分层方法(用红色箭头显示的依赖关系): 在此处输入图像描述 不幸的是,它重复了传统的依赖模型,其中高级模块依赖于低级模块。遵循依赖倒置的原则,IService 接口被移动到 WebProject 中。不幸的是,这在两个项目之间创建了一个循环引用: 在此处输入图像描述 为了避免循环引用,CompositionRoot 被移动到它自己的项目中: 在此处输入图像描述

给我留下了如何引导容器的问题(现在我不能从 WebProject 中直接引用它)?

在获取程序集执行初始化的目录的最佳方法的帮助下,可以通过反射来实现。

var assembly = System.Reflection.Assembly.LoadFile(Helper.AssemblyDirectory + "/DependencyInjectionProject.dll");
var type = assembly.GetType("DependencyInjectionProject.Bootstrapper");
IDependencyResolver resolver = (IDependencyResolver)type.GetMethod("Initialise").Invoke(null, null);
DependencyResolver.SetResolver(resolver);

为了简化构建,我将 DependencyInjectionProject 的构建目标设置为 WebProject bin 目录。我已经实现了我的目标;反向依赖项和编译时间检查容器配置,但我对这种方法并不完全满意,因为在 IIS Express 中运行 WebProject 时经常发生构建目标冲突。

我很想听听其他经验和方法来满足这些要求。我应该放弃编译时配置并采用基于文本的配置吗?是否有明显的层结构可以避免我没有看到的循环依赖的陷阱?

4

2 回答 2

0

组合根与 DI 容器不同。组合根是可执行文件的非常早期的入口层,DI Container 放置在那里。

DI Container 放在那里的原因之一是,入口级别没有被任何其他类调用。因此,当您在那里创建 DI Container 时,它将确保 DI Container 在最早的调用时构建,并防止空引用异常。可能还有其他好处,但我只是不知道。

我通常使用的是分层设计,包括:

  1. 领域模型(实体)
  2. 接口(参考 1)
  3. 服务(参考 1 和 2)
  4. dal(参考 1 和 2)
  5. UI(参考 1,2,3,4)

这种设计必须优先选择好的 SOC,并且可以防止 UI 直接访问存储库。dal 不了解服务和 UI。该服务不了解 DAL 和 UI。

我知道的一个缺点是这种设计允许 UI 无需服务直接访问 DAL。

不过,我仍然不知道这种设计的其他缺点。

于 2013-05-24T03:12:41.893 回答
-1

您永远不会希望将 IService 移动到 Web 项目中。除了循环引用(这不一定是交易破坏者,尽管 VS 不会让你这样做.. 它可以通过其他几种方式完成),这只是糟糕的设计。

取决于较低级别的模块,较高级别的模块绝对没有错。我不确定你为什么认为这是一个问题。依赖倒置实际上并不是指模块或程序集依赖,而是指接口依赖。(我在这里泛泛而谈,而不是专门针对 interface 关键字)。事实上,您可以在没有任何单独程序集的情况下拥有 DI……它们都可以在同一个程序集中。

但是,如果您确实选择将实现拆分为单独的程序集,则存在某些限制。这些主要是装配系统的实施问题。

模块依赖的问题并没有真正表现在只有两个模块上。当你有 3 个或更多时,问题就更大了。

我自己喜欢使用洋葱架构。在此方法中,您有一个单独的程序集,其中包含您的接口和常用类型(例如实体)。这个程序集没有很多代码,它主要是定义。

上面是您的数据层和业务层。这些取决于实体和接口的通用程序集。然后你有你的 UI 层,它取决于你的业务(或服务层,它通常只是你的业务层的一个外观)和公共层。

使用这种方法,UI 无法与 DAL 对话,反之亦然。业务层与 DAL 和 UI 对话。一切都依赖于具有很少功能代码的通用接口程序集,只有实体、DTO 和接口。因此,通用性只依赖于核心 .NET 东西。

    UI <--------> Service/Business <--------> DAL
     |                   |                     |
     +----------> Common (IService) <----------+

没有循环引用,每个人都得到他们想要的,只与他们需要的人交谈。

于 2013-05-24T04:15:48.327 回答