层次解释:
核心 – 包含域模型。例如这是商业对象及其关系。我正在使用实体框架来直观设计实体和它们之间的关系。它允许我为数据库生成一个脚本。我正在获得自动生成的类似POCO的模型,我可以在下一层(Persistence)中自由引用,因为它们很简单(即它们不是数据库特定的)。
持久性 – 存储库接口和实现。基本上CRUD操作在域模型上。
BusinessServices – 存储库周围的业务层。所有业务逻辑应该在这里(例如GetLargestTeam()等)。使用CRUD操作来组合返回对象或获取/过滤/存储数据。应包含所有业务规则和验证。
Web(或任何其他UI) – 在这种特殊情况下,它是一个MVC应用程序,但这个项目背后的想法是提供UI,由业务服务提供驱动。 UI项目消耗了业务层,不能直接访问存储库。 MVC项目有自己的View模型,它们是针对每个View的情况。我不是试图强迫它的域模型。
所以引用如下:
UI – >商务服务 – >存储库 – >核心对象
我喜欢什么
>我可以设计我的对象,而不是手动编码。我正进入(状态
代码生成的模型对象。
> UI由业务驱动/执行
层。不同的UI应用程序可以编码相同
商业模式。
混合的感觉:
>好的,我们有一个可插入的存储库实现,但是你真的有多少同一个持久化接口的不同实现?
> UI也是如此 – 我们有技术能力根据相同的业务规则来实现不同的UI应用程序,但是为什么我们可以简单地渲染不同的视图(移动,桌面等)?
>我不知道UI是否只能通过View模型与业务层进行通信,或者我应该像现在一样使用域模型来传输数据。为了显示,我正在使用视图模型,但是对于数据传输,我使用的是域模型。错误?
我不喜欢什么
>核心项目现在在其他所有项目中被引用 – 因为我需要访问域模型。在经典的洋葱架构中,核心仅由下一层引用。
> DbContext在.Core项目中实现,因为它是由Entity Framework生成的,与.edmx在同一个地方。我实际上想要使用.EDMX进行可视化模型设计,但是我觉得DbContext属于持久层,在数据库特定的存储库实现中。
作为一个最后的问题 – 什么是不是过度设计的好建筑(比如一个完整的洋葱,我们注射,服务定位器等),但同时提供一些合理的灵活性,在那里你会现实需要吗?
谢谢
解决方法
首先,我们来谈谈整体架构。
我可以看到,这不是一个真正的洋葱建筑。你忘记了最外层,“依赖关系分辨率”层。在洋葱架构中,根据这一层将Core接口与基础架构实施(Persistence项目所在的位置)进行连接。
以下是您在洋葱应用程序中找到的内容的简要说明。核心层中的内容是业务所特有的:域模型,业务流程…此层将所有技术实现需求定义为接口(即存储库接口,日志记录接口,会话接口…)。核心层不能引用任何外部库,并且没有技术特定的代码。第二层是基础设施层。此层为非业务核心接口提供实现。这是您调用DB,您的Web服务的地方…您可以引用所需的任何外部库,以提供实现,根据需要部署尽可能多的nugget软件包:-)。第三层是你的UI,你知道要放在哪里;-)最新的层,这是我上面谈到的依赖关系。
层次之间的依赖关系朝向中心。
以下是它的外观:
现在的问题是:如何适应您在洋葱架构中已编码的内容。
Core: contain the Domain model
是的,这是正确的地方!
Persistence – Repository interface and implementations
那么你需要使用实现来分离接口。接口需要移动到Core中,实现需要移入Infrastructure文件夹(您可以调用此项目Persistence)。
BusinessServices – A business layer around the repository. All the
business logic should be here
这需要在Core中移动,但是您不应该在这里使用存储库实现,只需操作界面!
Web (or any other UI) – In this particular case it’s an MVC
application
酷:-)
您将需要添加一个“Bootstrapper”项目,只需看看here,看看如何继续。
关于你的混合感觉:
我不会讨论有没有存储库的需要,你会在stackoverflow上找到很多答案。
在我的viewmodel项目中,我有一个名为“Builder”的文件夹。我的Builders可以与我的Business Services接口讨论,以获取数据。构建器将收到Core.Domain对象的列表,并将它们映射到正确的viewmodel中。
关于你不喜欢什么:
In classic Onion architecture,the core is referenced only by the next
layer.
假的! :-)每个层都需要Core来访问在那里定义的所有接口。
The DbContext is implemented in the .Core project,because it is being
generated by the Entity Framework,in the same place where the .edmx
is
再一次,一旦编辑与您的EDMX相关联的T4模板变得非常容易,这不是问题。您只需要更改生成的文件的路径,您可以在基础架构层中安装EDMX,并在Core.Domain项目中拥有POCO。
希望这可以帮助!