关于ASP.NET MVC Onion架构的意见

hya*_*kov 21 entity-framework onion-architecture asp.net-mvc-4

您对以下"通用"代码 - 第一个洋葱风格的ASP.NET MVC架构有何看法: 解决方案资源管理器的屏幕截图

这些层次解释说:

核心 - 包含域模型.例如,这是业务对象及其关系.我正在使用Entity Framework来可视化地设计实体及它们之间的关系.它让我为数据库生成一个脚本.我正在获得自动生成的类似POCO的模型,我可以在下一层(持久性)中自由引用,因为它们很简单(即它们不是特定于数据库的).

持久性 - 存储库接口和实现.基本上是对域模型的CRUD操作.

BusinessServices - 存储库周围的业务层.所有业务逻辑都应该在这里(例如GetLargestTeam(),等等).使用CRUD操作组成返回对象或获取/过滤/存储数据.应包含所有业务规则和验证.

Web(或任何其他UI) - 在这种特殊情况下,它是一个MVC应用程序,但该项目背后的想法是提供UI,由业务服务提供的驱动.UI项目使用Business层,无法直接访问Repository.MVC项目有自己的View模型,这些模型特定于每个View情境.我不是试图强制它域模型.

所以引用如下: UI - > Business Services - > Repository - > Core对象

我喜欢它:

  • 我可以设计我的对象,而不是手动编码.我正在获得代码生成的Model对象.
  • UI由业务层驱动/强制执行.可以针对同一商业模型对不同的UI应用程序进行编码.

关于:

  • 好的,我们有一个可插拔的存储库实现,但是你有多少次真正拥有相同持久性接口的不同实现?
  • UI也是如此 - 我们具有针对相同业务规则实现不同UI应用程序的技术能力,但是当我们可以简单地呈现不同的视图(移动,桌面等)时,为什么我们会这样做呢?
  • 我不确定UI是否应该只通过View模型与业务层进行通信,或者我应该像现在一样使用域模型来传输数据.为了显示,我使用的是视图模型,但是对于数据传输,我使用的是Domain模型.错误?

我不喜欢的:

  • Core项目现在在每个其他项目中引用 - 因为我想/必须访问Domain模型.在传统的Onion架构中,核心仅由下一层引用.
  • DbContext在.Core项目中实现,因为它是由实体框架生成的,位于.edmx所在的位置.我实际上想要使用.EDMX进行可视化模型设计,但我觉得DbContext属于Persistence层,位于特定于数据库的存储库实现中.

作为一个最后的问题 - 什么是一个没有过度设计的好建筑(比如一个完整的洋葱,我们有注射,服务定位器等),但同时提供一些合理的灵活性,在你想要的地方现实需要吗?

谢谢

Max*_*xSC 25

哇,这里有很多话要说!;-)

首先,我们来谈谈整体架构.

我在这里看到的是它并不是真正的洋葱架构.您忘记了最外层,即"依赖性解析"层.在Onion架构中,由此层将Core接口连接到Infrastructure实现(Persistence项目应该驻留在哪里).

以下是您应该在洋葱应用程序中找到的内容的简要说明.核心层中的内容是业务所特有的一切:域模型,业务工作流......此层将所有技术实现需求定义为接口(即:存储库的接口,日志记录接口,会话接口......).Core层不能引用任何外部库,也没有特定于技术的代码.第二层是Infrastructure层.该层提供非业务Core接口的实现.这是您调用数据库,Web服务的地方......您可以引用所需的任何外部库来提供实现,根据需要部署尽可能多的块包:-).第三层是你的用户界面,你知道要放在那里;-)和最新的层,这是我上面谈到的依赖性解决方案.

层之间的依赖方向朝向中心.

以下是它的外观:

洋葱App结构

现在的问题是:如何适应您已经在洋葱架构中编码的内容.

核心:包含域模型

是的,这是正确的地方!

持久性 - 存储库接口和实现

那么,您需要将接口与实现分开.需要将接口移动到Core中,并且需要将实现移动到Infrastructure文件夹中(您可以将此项目称为Persistence).

BusinessServices - 存储库周围的业务层.所有业务逻辑都应该在这里

这需要在Core中移动,但是你不应该在这里使用存储库实现,只需操作接口!

Web(或任何其他UI) - 在这种特殊情况下,它是一个MVC应用程序

很酷:-)

您需要添加一个"Bootstrapper"项目,只需看看这里如何继续.

关于你的复杂情绪:

我不会讨论是否需要存储库,你会在stackoverflow上找到很多答案.

在我的ViewModel项目中,我有一个名为"Builder"的文件夹.由我的构建者来讨论我的业务服务接口以获取数据.构建器将接收Core.Domain对象的列表,并将它们映射到正确的ViewModel.

关于你不喜欢的东西:

在传统的Onion架构中,核心仅由下一层引用.

错!:-)每一层都需要Core才能访问那里定义的所有接口.

DbContext是在.Core项目中实现的,因为它是由实体框架生成的,在.edmx所在的同一个地方.

再一次,只要编辑与EDMX相关的T4模板非常容易,就不会有问题.您只需要更改生成的文件的路径,您就可以在Infrastructure层中使用EDMX,在Core.Domain项目中使用POCO.

希望这可以帮助!