IoC对泛型的关注点分离

时间:2012-04-21 20:18:47

标签: asp.net-mvc-3 architecture inversion-of-control unity-container

我的项目安排如下

  • ASP.NET MVC 3 WebApp
  • Domain.Core - Interfaces [library]
  • Domain.Core.Entity - 实体[library]
  • Infrastructure.Core - 接口的实现[library]
  • Infrastructure.IoC - 使用Unity作为实现控制反转的手段[library]

困境如下:

如果我要将一个泛型方法添加到我的Domain.Core中的接口,如下所示,我收到一个编译错误,要求我在Infrastructure.IoC项目中添加对Domain.Core.Entity的引用。

T Get<T>(int Id) where T : EntityBase, new();

T可以是EntityBase或Blog类,它继承自EntityBase或其他一些都从EntityBase继承的实体。我们的想法是根据提供的子类返回一个实体,以便子类加载实现EntityBase的所有类所需的默认数据。

所以,问题有两个:

  1. 最好不要在IoC项目中引用Domain.Core.Entity项目并保持干净吗?

  2. 如何在不影响参考文献清洁的情况下实现上述目标?

  3. 谢谢。

    注意:我在这里经历了一些问题来搜索这个主题,但没有看到任何问题。如果您确实看到了,请告诉我,我将删除此问题。

2 个答案:

答案 0 :(得分:4)

使用依赖注入,最好有一个单个组件,负责组合所有各种协作者。这是Nat Pryce的Third-Party Connect概念中的第三方,或者我称之为Composition Root的概念。在上面概述的体系结构中,这个责任似乎落在了Infrastructure.IoC上,所以考虑到这种结构,将Infrastructure.IoC中的引用添加到Domain.Core.Entity没有任何问题 - 事实上,我觉得如果它更令人惊讶不是这样。

然而,作为反馈的总体内容,我认为值得考虑具有单独的Infrastructure.IoC库实际获得的好处。该应用程序的入口点(ASP.NET MVC应用程序)需要引用Infrastructure.IoC,它还必须引用所有库才能组成它们。因此,ASP.NET MVC应用程序最终会对所有其他库进行间接引用,您也可以合并这两个库。

(从技术上讲,您可以依靠某种后期绑定机制(例如XML配置或约定优于配置)来解耦各种库,但是Infrastructure.IoC的概念职责将保持不变。)

有关详情,请阅读以下答案:Ioc/DI - Why do I have to reference all layers/assemblies in entry application?

答案 1 :(得分:3)

为什么要从Domain.Core.Entity拆分Domain.Core?为什么要从Infrastructure.IoC拆分Infrastructure.Core?

我认为你可以逃脱3项目结构:

  1. 域 - 对其他2个项目没有依赖关系。可能包含实体和接口。
  2. 基础架构 - 包含接口实现和Unity容器。仅取决于域项目。
  3. MVC - 依赖于域和基础架构。
  4. 如果您担心针对具体类而不是接口进行编程,请为Infrastructure项目中的类提供不同的命名空间。那么你应该只使用该命名空间几次(在Global.asax或bootstrapper中),如果有的话。

    这样很清楚哪些项目取决于什么。由于您使用的是统一,因此这是onion architecture的一种形式。如果您稍后发现应将基础结构或域拆分为多个项目,则可以重构。

    IMO,当您在域项目中使用System.Web.Mvc或Microsoft.Practices.Unity 等参考 时,依赖关系只会变得混乱或不干净。就像马克在他的回答中所说的那样,你的“洋葱”的外层将依赖于内层,你无法避免这种情况。但是,尝试让域名专注于其核心业务,尽可能避免在UI中使用它的详细信息。

相关问题