Inversion of control 洋葱建筑与国际奥委会矛盾吗

Inversion of control 洋葱建筑与国际奥委会矛盾吗,inversion-of-control,onion-architecture,Inversion Of Control,Onion Architecture,Jeffrey Palermo开创了洋葱架构,我发现这是一个很好的方法 然而,如果我的理解正确的话,他的陈述“内层定义接口。外层实现接口”似乎与IoC相矛盾,IoC指出使用者定义接口,提供者实现接口,即控制权在于使用者而不是提供者 这一原则对我来说很有意义,因为,假设你正在编写一个UI,这一原则意味着你可以继续创建你的UI,而不需要知道你将要调用的服务的任何信息,因为你负责定义一个界面,这个界面公开了你需要的所有功能 因此,Jeffrey的陈述似乎自相矛盾,让我对合同(接口定义)的位置感到困惑

Jeffrey Palermo开创了洋葱架构,我发现这是一个很好的方法

然而,如果我的理解正确的话,他的陈述“内层定义接口。外层实现接口”似乎与IoC相矛盾,IoC指出使用者定义接口,提供者实现接口,即控制权在于使用者而不是提供者

这一原则对我来说很有意义,因为,假设你正在编写一个UI,这一原则意味着你可以继续创建你的UI,而不需要知道你将要调用的服务的任何信息,因为你负责定义一个界面,这个界面公开了你需要的所有功能

因此,Jeffrey的陈述似乎自相矛盾,让我对合同(接口定义)的位置感到困惑,因为它似乎暗示: 域层 MyEntity IMyService 服务 MyEntityService:IMyService

既然域下面没有层,我该把IMyEntity放在哪里呢。这还意味着,在域存在并定义了IMyService之前,我无法创建表示项目

正如我旁白所说,我应该把IMyEntityRepository和MyEntityRepository放在哪里?既然服务依赖于IMyEntityRepository,而MyEntityRepository依赖于IMyEntity

那么,从哪里开始呢?:-)

让我们从国际奥委会的真正作用开始。根据,

控制反转是一种编程技术,其中 耦合在运行时由汇编器对象绑定,通常是 在编译时不知道

在您的情况下,UI将操纵服务接口,而不知道在运行时绑定的服务实现。定义这些服务接口并不是消费者的责任;它们将在洋葱架构的应用程序核心中定义,但我们将在后面看到

“内层定义接口,外层实现接口”,洋葱架构就是这样设计的,但不要忘记最外层是IOC!由IOC在运行时将接口与正确的实现绑定起来

你说得对,如果你要操作的界面没有至少一个可用的实现,你的UI就无法工作。但是在这种情况下,如果出于任何原因,你需要首先建立你的UI,考虑使用嘲讽框架! 最后一个问题是关于需要将IMyEntityRepository和MyEntityRepository类放置在何处。嗯,这是最简单的部分;-)IMyEntityRepository肯定需要放在应用程序核心中。所有实体、服务接口、存储库接口以及任何需要位于同一位置的接口。MyEntityRepository实现应该放在基础架构层的某个地方,因为他的角色主要是处理从数据库中获取数据


希望有帮助

我与杰弗里共事多年,我想说,国际奥委会是使洋葱建筑成为可能的不可或缺的因素。外部依赖关系的接口是在依赖关系很少(如果有的话)的项目中定义的(换句话说,项目位于洋葱的“中心”)。实现依赖于外部依赖关系的接口的类位于项目的边缘/表面。然后,需要IoC容器在运行时将洋葱边缘的类实现“连接”到洋葱核心的接口。

我们在我的项目中实现了洋葱,概念上非常简单

  • 创建一个只包含接口和POCO的项目,我们现在称之为合同
  • 创建一个或多个包含接口实现和所有第三方内容(如NHibernate映射)的项目,我们称此实现为
  • 添加对需要使用此功能的项目的合同的直接引用,但不添加对这些项目的实现的引用
  • 在复合根目录(应用程序入口点)中,项目做两件事(1)作为构建的一部分,将最新版本的实现复制到配置的位置(我们使用AppSettings进行配置,但这里有很多选项)(2)让容器扫描配置的位置以获取实现Dll
  • 这种方法只允许您依赖契约,其思想是您可以切换实现,因此,如果您希望在将来转移到实体框架或其他东西,您只需要使用该框架重新实现实现


    我们还将NHibernate DLL复制到配置的扫描位置,这允许我们使体系结构具有防御性,因此很难不遵循它,因为NHibernate仅在应该使用的地方可用。

    onion体系结构中的接口是层所依赖的接口(即消耗),它的实现确实是由外层提供的

    更具体地说,架构本身并没有说您必须抽象接口背后的业务逻辑(您可能无论如何都应该这样做,但这是另一回事)。所说的是,该层的依赖项应该建模为接口,以便由外层提供实现

    最好的例子是基础架构代码,尤其是数据访问。您的业务逻辑需要加载和存储数据,因此它定义了将使用的接口。外层将提供一个使用NHibernate或EF的实现

    实际上,底层(来自DIP;即数据访问和其他商品)位于洋葱的最外层,而高层(即业务逻辑)则更靠近中心

    另请参见使用实体、用例和接口适配器替换域、业务逻辑和更多业务逻辑术语的内容