洋葱架构同一层的依赖关系:基础设施和Web通信
我正在使用所描述的 洋葱架构 设计一个 ASP.NET MVC 应用程序作者:杰弗里·巴勒莫。
这是一个 ASP.NET MVC 2.0 项目,我要求所有视图都使用专用视图模型进行强类型化——我们不会将域模型传递给我们的视图。我们使用 AutoMapper 进行转换——AutoMapper 在基础设施中是隔离的,Web 不知道也不关心 AutoMapper 正在被使用。
目前,我正在 Web 项目中定义 IViewModelMapping 接口 - 只是因为该服务将由控制器使用,并且它可以直接访问自己的视图模型。这样,界面就可以访问域模型(在 Core 中)和视图模型(在 Web 中)。
为了提供 IViewModelMapping 接口的实际实现,我在基础设施项目中创建了一个 ObjectMapping 命名空间,它将实际映射实现隔离到洋葱的内部结构。为此,这将要求基础设施同时依赖于核心和 Web。
我的问题是:由于这两个项目在技术上都位于洋葱的外围(在同一层中)——是否允许一个项目依赖于该层中的另一个项目?有人注意到这个设计有任何潜在的陷阱吗?
另一种设计是将 IViewMapper 接口移至 Core 中 —— 但这是不可能的,因为 Core 无法访问 ViewModel 类。我还可以将视图模型移至 Core,但我觉得它们不属于那里,因为它们特定于 UI 层。
建议的架构如下 - 请注意,基础设施依赖于核心和 Web。 Web 保持隔离,只能访问核心业务逻辑。
I am designing an ASP.NET MVC application using the Onion Architecture described by Jeffrey Palermo.
It is an ASP.NET MVC 2.0 project, where I am requiring that all views be strongly typed using dedicated View Models -- we will not be passing domain models to our views. We are using AutoMapper to do the translation -- AutoMapper is isolated in the infrastructure, Web does not know or care that AutoMapper is being used.
Currently, I am defining the IViewModelMapping interfaces in the Web project -- simply because this service will be used by the Controllers and it has direct access to its own View Models. This way the interface can access both the Domain Models (in Core) and the View Models (in Web).
In order to provide the actual implementation of the IViewModelMapping interfaces, I created an ObjectMapping namespace in the Infrastructure project, which will isolate the actual mapping implementation to the Intrastructure of the onion. In doing so, this will require Infrastructure to have a dependency on BOTH Core AND Web.
My question is: since both of these projects are technically on the outskirts of the onion (in the same layer) -- is one project allowed to have a dependency on another project in that layer? Does anyone notice any potential pitfalls with this design?
An alternative design would be moving the IViewMapper interfaces into Core -- but this would be impossible because Core does not have access to the ViewModel classes. I could also move the view models into Core, but I feel like they would not belong there, since they are specific to the UI layer.
The proposed architecture is as follows -- notice that Infrastructure has a dependency on Core AND Web. Web remains isolated and only has access to the Core business logic.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不希望基础架构依赖于 UI(Web),这是正确的,但有时我会打破该规则。
我想用 Map() 方法创建 IMapper,而不是 IViewModelMapping。然后,该接口可以具有可能与视图模型映射有关的实现,或者可能只是常规映射。无论哪种方式,该接口都可以位于 Core 中,因为它在语义上不绑定到任何类型的模型。
很棒的图形。我希望我回答了你问题的实质。洋葱架构的总体理念是将业务逻辑和模型保留在应用程序的中间(核心),并将依赖项尽可能向外推。
You are correct that you don't want Infrastructure to depend on UI(Web), but I break that rule sometimes.
I would think instead of IViewModelMapping, create IMapper with method Map(). Then, the interface can have implementations that might have to do with view model mapping, or maybe just regular mapping. Either way, that interface can be in Core because it is not semantically bound to any type of model.
Great graphic. I hope I answered the meat of your question. The overall philosophy of the Onion Architecture is to keep your business logic and model in the middle (Core) of your application and push your dependencies as far outward as possible.
尝试将对象映射移至Web层。
Try to move Object Mapping into Web layer.
您的 Web/UI 层可以依赖于基础设施层。但Web对基础设施层的依赖并不是一个好的设计。洋葱架构表示将您的依赖项尽可能向外推。
您可以在 UI 中创建一个“\Builder”文件夹。在其中添加一个接口文件,例如.. IBuilder 或 IMapper 并在其中声明一个像 ConvertToViewModel 或 CreateMapping 这样的方法。无论你喜欢什么。
*建造者
**IBuilder.cs - 在这里声明一个方法。
**Builder.cs -- - 在这里实现该方法,定义 ViewModel 与其对应的 DomainModel(来自核心层的引用)之间的映射,并在此处返回适当的 ViewModel。
Your Web/UI layer can be dependent on Infrastructure layer. But it's not a good design to have dependency of Web on Infrastructure layer. Onion architecture says push your dependencies as far outward as possible.
You can create a "\Builder" folder in UI. Add one interface file in it,example.. IBuilder or IMapper and declare a method like ConvertToViewModel or CreateMapping in it. whatever you like.
*Builder
**IBuilder.cs -declare a method here.
**Builder.cs -- - Implement the method here,define mapping between a ViewModel and it's corresponding DomainModel( reference from core layer) and return appropriate ViewModel here.