2

Jeffrey Palermo 开创了洋葱架构,我找到了一个很好的方法。

http://www.headspring.com/jeffrey/onion-architecture-part-4-after-four-years/

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

这个原则对我来说很有意义,因为,假设你正在编写一个 UI,这个原则意味着你可以继续创建你的 UI,而不需要对你将要调用的服务一无所知,因为你负责定义暴露所有服务的接口您需要的功能。

因此,为此,Jeffreys 的声明似乎自相矛盾,让我对将合同(接口定义)放在哪里感到困惑,因为它似乎暗示: Domain Layer MyEntity IMyService Service MyEntityService : IMyService

由于域下面没有层,我将 IMyEntity 放在哪里。这也意味着在域存在并定义 IMyService 之前,我无法创建演示项目。

正如我的旁注,我在哪里放置 IMyEntityRepository 和 MyEntityRepository ?由于服务依赖于 IMyEntityRepository 而 MyEntityRepository 依赖于 IMyEntity

4

4 回答 4

5

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

让我们从国际奥委会的真正角色开始。根据维基百科

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

在您的情况下,您的 UI 将在不知道将在运行时绑定的服务实现的情况下操作服务接口。定义这些服务接口不是由消费者决定的;它们将在您的 Onion 架构的应用程序核心中定义,但我们稍后会看到。

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

您说得对,如果没有至少一种可用于您将操作的接口的实现,您的 UI 将无法工作。但在这种情况下,如果出于任何原因需要先构建 UI,请考虑使用模拟框架!

您的最后一个问题是关于您需要放置 IMyEntityRepository 和 MyEntityRepository 类的位置。好吧,这很容易;-) IMyEntityRepository 肯定需要放在您的应用程序核心中。您的所有实体、服务接口、存储库接口以及任何需要位于同一位置的接口。MyEntityRepository 实现应该放在基础设施层的某个地方,因为他的角色主要是处理从数据库中获取数据。

希望有帮助!

于 2013-03-01T15:24:14.763 回答
4

我与 Jeffrey 共事多年,我想说 IoC 是使 Onion Architecture 成为可能不可或缺的一部分。外部依赖项的接口在具有很少(如果有的话)依赖项的项目中定义(换句话说,位于洋葱“中心”的项目)。实现那些依赖于外部依赖项的接口的类位于洋葱边缘/表面的项目中。因此,需要 IoC 容器在运行时将洋葱边缘的类实现“连接”到洋葱核心的接口。

于 2013-03-01T16:17:01.057 回答
2

我们已经在我的项目中实现了 Onion,它在概念上非常简单。

  1. 创建一个只包含接口和 POCO 的项目,我们现在称之为 Contract
  2. 创建一个或多个项目,其中包含您的接口和所有 3rd 方的实现,例如 NHibernate 映射,我们称之为实现
  3. 从需要使用此功能的项目中添加对 Contract 的直接引用,但不要从这些项目中添加对 Implementation 的引用
  4. 在您的复合根(应用程序入口点)项目中做两件事(1)作为构建的一部分,将最新版本的实现复制到配置的位置(我们使用 AppSettings 进行配置,但这里有很多选项)(2)让您的容器扫描您的实施 Dll 的配置位置

这种方法允许您仅依赖合同,其想法是您可以切换实现,因此如果您想在未来迁移到实体框架或其他东西,您只需使用该框架重新实现实现。

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

于 2013-03-01T19:01:06.387 回答
0

洋葱架构中的接口是层所依赖的接口(即消费),其实现确实由外层提供。

更具体地说,架构本身并没有说您必须抽象接口背后的业务逻辑(就依赖倒置原则而言,无论如何您都应该这样做,但那是另一回事了)。所说的是层的依赖关系应该建模为接口,因此可以由外层提供实现。

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

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

另请参阅http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html它用实体用例接口适配器替换了业务逻辑更多业务逻辑术语IMO 更容易推理。你离中心越远,你对用户看到和使用的东西就越具体;越靠近中心越通用;中心是那些与您的企业横向的东西,然后特定于您的应用程序的用例更多地不决定它们将如何使用或在哪个环境(哪个数据库,哪个 UI 等),然后您将在您的用例和您的技术框架(ASP.NET MVC、WCF、WPF——在非 Web 场景中——、EF、NHibernate 等)之间制作适配器

于 2013-04-27T14:00:49.730 回答