你对下面的“通用”代码优先洋葱风格的ASP.NET MVC架构的意见:
层,解释:
核心 -包含域模型。 例如,这是业务对象和他们的关系。 我使用实体框架来直观地设计实体以及它们之间的关系。 这让我产生了数据库的脚本。 我收到自动生成的POCO般的模型,我可以自由地指的是下一层(持久性),因为它们是简单的(即它们不是特定数据库)。
持久性 -库接口和实现。 域模型基本上CRUD操作。
BusinessServices -各地仓库业务层。 所有的业务逻辑应该在这里(如GetLargestTeam()
等)。 使用CRUD操作组成的回报对象或获取/过滤/存储数据。 应该包含所有的业务规则和验证。
网页(或任何其他UI) -在这种特殊情况下,它是一个MVC应用程序,但这个项目背后的想法是提供用户界面,通过什么商务服务提供驱动。 该UI项目消耗的业务层和具有资源库没有直接联系。 该MVC项目有着自己的看法车型,这是具体到每一个查看情况。 我不是要强行给它域模型。
所以引用是这样的:用户界面- >商业服务- >库- >核心对象
我喜欢它:
- 我可以设计我的对象,而不是将它们手工编码。 我得到的代码生成的模型对象。
- UI被驱动/由业务层执行。 不同的UI应用程序可以对同一个商业模式进行编码。
约感慨:
- 好吧,我们有一个可插拔的仓库实现,但你多久真的有同一个持久性接口的不同实现?
- 这同样适用于用户界面 - 我们必须对相同的业务规则实现不同的UI应用程序的技术能力,但我们为什么要这么做,我们可以简单地呈现不同的视图(移动,桌面等)?
- 我不知道如果UI应与业务层通过查看模型只有沟通,或者我应该使用域模型来传输数据,我现在要做的。 对于显示器,我使用视图模型,但是对于数据传输,我使用的域模型。 错误?
我不喜欢:
- 核心项目现在在所有其他项目中引用 - 因为我想/需要访问域模型。 在经典洋葱结构,所述芯仅由下一层中引用。
- 该的DbContext在项目。核心实现的,因为它是由实体框架生成的,在的.edmx是同一个地方。 其实我是想使用的.edmx的视觉模型设计,但我觉得像的DbContext属于持久层,内的特定数据库的仓库实现的地方。
作为最后一个问题 - 什么是一个很好的架构,它是不是过度设计(如一个成熟的洋葱,我们在那里打针,服务定位器等),但在同一时间提供了一些合理的灵活性,在地方,你会现实需要吗?
谢谢
哇,有很多在这里说! ;-)
首先,让我们来谈谈整体架构。
我可以在这里看到的是,它不是一个真正的洋葱架构。 你忘了最外层,“依赖的决议”层。 在洋葱架构,它是由这层直径达核心接口,基础设施实现(在您的持久性项目应该驻留)。
下面是你应该在洋葱应用程序查找一个简要说明。 善有善报,在核心层就是一切独特的业务:领域模型,业务工作流程......这层定义了所有的技术实现需求的接口(即:库界面,登录界面,会话的接口...)。 核心层不能引用任何外部库并且没有技术特定代码。 第二层是基础结构层。 这一层提供非商业核心接口的实现。 这是你打电话给你的数据库,Web服务中...你可以参考你需要提供实现任何外部库,部署为多块的包,只要你想:-)。 第三层是你的用户界面,那么你知道要放什么东西在那里;-)而最新层,它的解决依赖我上面讲的。
层之间的依赖关系的方向是朝向中心。
下面是它可能看起来像:
现在的问题是:如何适应了你已经在洋葱架构编码。
核心:包含域模型
是的,这是正确的地方!
持久性 - 库接口和实现
那么,你就需要与实现独立的接口。 接口需要被移动到核心和实现需要被移动到基础设施文件夹(你可以把这个项目持久性)。
BusinessServices - 各地仓库业务层。 所有的业务逻辑应该在这里
这需要在核心移动,但你不应该使用存储库实现这里,只是操作界面!
网页(或任何其他UI) - 在这种特殊情况下,它是一个MVC应用程序
酷:-)
您将需要添加一个“引导程序”的项目,只要看看这里 ,看看如何进行。
关于你的感慨:
我不会讨论有关其资料库的需要与否,你会发现很多关于计算器的答案。
在我的视图模型的项目我有一个叫做“生成器”的文件夹。 这是给我的建设者,以获得数据与我的业务服务接口来讨论。 建设者将获得Core.Domain对象的列表,并把它们映射到正确的视图模型。
关于你不喜欢的东西:
在经典洋葱结构,所述芯仅由下一层中引用。
假的! :-)每一层的核心需求有机会获得在那里定义的所有接口。
该的DbContext在项目。核心实现的,因为它是由实体框架生成的,在同一个地方,是的.edmx
再次,尽快不是一个问题,因为它真的很容易编辑与您EDMX相关的T4模板。 你只需要更改生成文件的路径,你可以有EDMX在基础设施层和POCO在你的Core.Domain项目。
希望这可以帮助!
我注入我的服务到我的控制器。 该服务返回DTO的驻留在核心。 你看起来不错的型号,我不使用仓库模式,但很多人做的。 我很难在这种类型的结构这就是为什么我选择使用NHibernate的与EF工作。
一个可能的回答你的最后一个问题。
- 核心
- 域
- DI
- 基础设施
- 介绍
- 服务
在我看来:
- “以经典洋葱结构,所述芯仅由下一层中引用”。 这是不正确,核心应是任何层参考...记住层之间的依赖的该方向是朝向中心(核心)。
“层上面可以使用它们之下的任何层”通过杰弗里巴勒莫http://jeffreypalermo.com/blog/the-onion-architecture-part-3/
- 关于您的EF,它是在错误的地方....应该是在基础设施层不能在核心层。 并使用POCO发生器创造核心/模型实体(POCO类)。 或者使用自动映射,所以你可以映射核心模型(业务对象)实体模型(EF实体)
在另一方面,我创建了用洋葱架构显示层以及应如何实施之间的依赖关系的简单应用。 http://www.jaider.net/posts/935-onion-architecture-in-action-get-started/
你所做的看起来相当不错,基本上我看到有很多两个标准体系之一。
约感慨:
好吧,我们有一个可插拔的仓库实现,但你多久真的有同一个持久性接口的不同实现?
可插拔往往被吹捧为好设计,但我从来没有见过一次,一队交换了重大执行一些别的东西。 他们只是修改现有的东西。 IMHO“可插拔”仅是用于能够嘲笑用于自动化单元测试部件是有用的。
我不知道如果UI应与业务层通过查看模型只有沟通,或者我应该使用域模型来传输数据,我现在要做的。 对于显示器,我使用视图模型,但是对于数据传输,我使用的域模型。 错误?
我估计视图模型是一个UI(MVC的Web)的关注,如果添加了不同类型的UI例如,它可能不需要视图模型或可能需要不同的东西。 所以我觉得在业务层应该返回域实体,并允许它们被映射到UI层,以查看模型。
我不喜欢:
核心项目现在在所有其他项目中引用 - 因为我想/需要访问域模型。 在经典洋葱结构,所述芯仅由下一层中引用。
正如其他人说,这是很正常的。 通常一切都结束了其对域名的依赖。
该的DbContext在项目。核心实现的,因为它是由实体框架生成的,在的.edmx是同一个地方。 其实我是想使用的.edmx的视觉模型设计,但我觉得像的DbContext属于持久层,内的特定数据库的仓库实现的地方。
我认为这是实体框架的结果。 如果你用它在你实际上可以“代码优先”模式 - 与通常都 - 都在你叫什么核心与域的持久化层(表示为POCO类)的背景和资源库。
作为最后一个问题 - 什么是一个很好的架构,它是不是过度设计(如一个成熟的洋葱,我们在那里打针,服务定位器等),但在同一时间提供了一些合理的灵活性,在地方,你会现实需要吗?
正如我提到了上面,我不会担心需要更换的事情了,除了允许自动单元测试。 除非有您知道某个特定需求将使这很有可能。
祝好运!