同层洋葱架构依赖:基础设施和Web通信

Posted

技术标签:

【中文标题】同层洋葱架构依赖:基础设施和Web通信【英文标题】:Onion archicecture dependencies in the same layer: Infrastructure and Web communicating 【发布时间】:2011-01-21 03:10:00 【问题描述】:

我正在使用 Jeffrey Palermo 描述的 Onion Architecture 设计一个 ASP.NET MVC 应用程序。

这是一个 ASP.NET MVC 2.0 项目,我要求所有视图都使用专用视图模型进行强类型化——我们不会将域模型传递给我们的视图。我们正在使用 AutoMapper 进行翻译——AutoMapper 在基础设施中是孤立的,Web 不知道也不关心 AutoMapper 正在被使用。

目前,我正在 Web 项目中定义 IViewModelMapping 接口——仅仅是因为该服务将由控制器使用,并且它可以直接访问自己的视图模型。通过这种方式,界面可以访问域模型(在核心中)和视图模型(在 Web 中)。

为了提供 IViewModelMapping 接口的实际实现,我在 Infrastructure 项目中创建了一个 ObjectMapping 命名空间,它将实际映射实现隔离到洋葱的 Intrastructure。在这样做时,这将要求基础架构同时依赖于核心和 Web。

我的问题是:由于这两个项目在技术上都位于洋葱的郊区(在同一层)——是否允许一个项目依赖于该层中的另一个项目?有没有人注意到这种设计有任何潜在的缺陷?

另一种设计是将 IViewMapper 接口移动到 Core 中——但这是不可能的,因为 Core 无权访问 ViewModel 类。我也可以将视图模型移动到 Core,但我觉得它们不属于那里,因为它们是特定于 UI 层的。

建议的架构如下——注意基础设施依赖于Core AND Web。 Web 保持隔离状态,只能访问核心业务逻辑。

http://www.matthidinger.com/images/onion-arch.png

【问题讨论】:

您选择并完成的最终设计是什么?有趣的是查看更新后的图表以及映射的一些类结构:) 问题:为什么依赖解析层Web层有依赖? Controllers 不应该对 Dependency Resolution Layer 有依赖吗? 【参考方案1】:

您不希望基础架构依赖于 UI(Web) 是正确的,但我有时会违反该规则。

我想用 Map() 方法创建 IMapper,而不是 IViewModelMapping。然后,接口可以具有可能与视图模型映射有关的实现,或者可能只是常规映射。无论哪种方式,该接口都可以在 Core 中,因为它在语义上没有绑定到任何类型的模型。

很棒的图形。我希望我回答了你的问题。 Onion 架构的总体理念是将业务逻辑和模型保持在应用程序的中间(核心),并尽可能将依赖项向外推。

【讨论】:

谢谢杰弗里。现在我要重新考虑设计,但可能会保持原样,直到它给我带来任何重大头痛。对我来说最重要的是我不会做出任何以后无法逆转的决定:)【参考方案2】:

尝试将Object Mapping移动到Web层。

【讨论】:

【参考方案3】:

您的 Web/UI 层可以依赖于基础架构层。但是,Web 对 Infrastructure 层的依赖并不是一个好的设计。 Onion 架构表示将您的依赖项尽可能向外推。

您可以在 UI 中创建一个“\Builder”文件夹。在其中添加一个接口文件,例如.. IBuilder 或 IMapper 并在其中声明 ConvertToViewModel 或 CreateMapping 之类的方法。随心所欲。

*生成器 **IBuilder.cs - 在此处声明一个方法。 **Builder.cs -- 在此处实现该方法,定义 ViewModel 与其对应的 DomainModel 之间的映射(来自核心层的引用)并在此处返回适当的 ViewModel。

【讨论】:

以上是关于同层洋葱架构依赖:基础设施和Web通信的主要内容,如果未能解决你的问题,请参考以下文章

DDD—分层架构洋葱架构六边形架构

将 ASP.NET 身份与核心域模型解耦 - 洋葱架构

Java Web系列:Spring依赖注入基础

DDD和“洋葱架构”之间有什么关系?

领域驱动设计和CQRS落地

第一章 Web应用程序开发基础