问题标签 [onion-architecture]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1213 浏览

entity-framework - 通用存储库和泄漏抽象

我正在实现存储库模式。我这样做的主要原因:

  • 将客户端代码从持久性细节中抽象出来(实体框架)
  • 支持可测试性

通用存储库与否?

我遇到的问题是我是否应该有一个通用存储库。一种IQueryable<T> Query()方法将为调用代码提供构造特定查询的方法。这里的问题是这是泄漏的抽象——实体框架的细节现在正在泄漏到我的客户端代码中。

在此处输入图像描述

  • 这将如何影响单元测试? 我还能ICustomerRepository用这个实现来模拟吗?

  • 这种效果会如何替换我的持久层?像 Azure 存储表或 NHibernate。

否则我将不得不在 上实现非常具体的查询方法ICustomerRepository,例如GetIsActiveByFirstName()GetIsActiveByDistrict()。我非常不喜欢这种方式,因为我的存储库类将挤满不同的查询方法。这个系统有数百个模型,因此可能有数百甚至数千个这样的方法来编写和维护。

0 投票
2 回答
4147 浏览

entity-framework - 存储库模式:删除聚合根

从存储库中删除模型(聚合根)时,也必须删除所有关联的聚合。

我正在努力在我的存储库模式的实体框架 6 实现中实现这一点

在我的示例中,我想CustomerCustomerRepository. 所有客户的Order对象也应该被删除。

存储库(精简):

ICustomerRepositoryCustomerRepository(EF 实施):

客户端代码:

抛出异常:

System.InvalidOperationException:操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

除了打电话item.Orders.Clear()向 EF 表明必须删除这些关联外,我会。

0 投票
2 回答
1746 浏览

entity-framework - 使用 EF Fluent API 将域模型映射到数据库

下面是通过 Entity Framework 6 Fluent API 直接映射到数据库的项目代码优先类:

领域驱动设计中的贫血模型是一种反模式。我想在我的域模型中使用同一个类,而不是创建一个单独的Project域类并且必须在存储库中执行两者之间的复杂映射(以及我们拥有的数百个其他模型)。

这就是Project域模型类的外观:

根据我的阅读,我可以使用 EF 的 Fluent API 映射到私有字段。

这里有什么缺点吗?我是在走不必要的捷径吗?

我能预见的唯一问题是,当业务域模型本质上由来自两个或多个数据实体的数据组成时。

0 投票
1 回答
398 浏览

c# - 通过在领域模型中使用 IoC 来打破“无处不在的语言”?

我的问题是关于Udi对域事件的解决方案,尤其是类DomainEvents(参见下面的代码)

摘自 Udi 的代码。它以静态类的形式存在域模型。

从上面的代码中,静态成员IContainer在域模型中创建了一个 ioc-container-dependency。虽然我不确定 UdiIContainer是接口还是实际的 IoC 容器。

我在他的样本中看不到这样的东西:

我的第一个问题是:课堂上这是IContainer什么DomainEvents如果它真的是一个 IoC 容器,那它不是打破了“在域中没有基础设施”的规则吗?(如果我错了请纠正我)

DDD 的想法不就是将基础设施与域分离吗?

我的第二个问题是:DomainEvents本身是否违反了“DDD 无处不在的语言”的规则?因为它的实现不属于任何领域。

0 投票
1 回答
1468 浏览

winforms - 在 WinForms 应用程序的 Unity Container 中加载依赖项

解决方案结构(部分)

这就是解决方案部分的样子。

由于我在 Winforms 环境中使用洋葱架构,因此我有 UI、基础设施和核心层。所有层都使用依赖注入松散耦合。我想要实现的是,每当加载来自帐户表单(类库)的表单时,所有依赖项都应该加载到 UnityContainer 中,即注册的类型。这些依赖项是核心和基础设施项目中存在的接口和实现。

我的困惑是我应该在哪里编写代码来注册依赖项?这个应用程序的组合根是什么?请注意,来自 Accounts Forms、HR Forms 等的表单都是使用 Main Windows 应用程序中的反射加载的,该应用程序仅引用 Base Forms Project。

根据 Eben Roux 的建议

这是加载程序集时我执行wireup代码的方式:

这是具有 WireUp 方法的模块:

所以我现在的问题是:

  1. 将 Container 存储为 Shared 并使用它通过 Resolve 方法解决依赖关系是否正确?
  2. 我封装容器的 Resolve 行为的方式存在问题。什么是正确的语法?我不想在每个表单上引用 Unity 以便能够调用 Resolve 方法,所以我封装了我自己的 Resolve 方法。通过这种方式,如果我想更改 IOC 容器而不更改容器引用,我可以很容易地用另一个替换 AccountModule。
0 投票
6 回答
46673 浏览

.net - 领域模型和实体框架之间的存储库模式和映射

我的存储库处理并为富域模型提供持久性。我不想将贫血的实体框架数据实体暴露给我的业务层,因此我需要某种方式在它们之间进行映射。

在大多数情况下,从数据实体构造域模型实例需要使用参数化的构造函数和方法(因为它很丰富)。它不像属性/字段匹配那么简单。AutoMapper 可用于相反的情况(映射到数据实体),但不能用于创建域模型。

下面是我的存储库模式的核心。

该类EntityFrameworkRepository适用于两种通用类型:

  • TDomainModel: 富域模型
  • TEntityModel: Entity Framework 数据实体

定义了两个抽象方法:

  • ToDataEntity(TDomainModel): 转换为数据实体(forAdd()Update()方法)
  • ToDomainModel(TEntityModel):构建领域模型(用于Find()方法)。

这些方法的具体实现将定义相关存储库所需的映射。

这是存储库实现的基本示例:

问题:

ACompany可能由许多Departments. 如果我想CompanyRepository在获取 a 时急切地加载这些,Company那么我将在哪里定义 aDepartment和 a之间的映射DepartmentDataEntity

我可以在 中提供更多映射方法CompanyRepository,但这很快就会变得混乱。很快就会在整个系统中出现重复的映射方法。

解决上述问题的更好方法是什么?

0 投票
2 回答
1190 浏览

asp.net-mvc - Onion Architecture 我们应该将领域模型注入表示层吗?

我正在尝试为 ASP.Net MVC 5 项目实现 Onion 架构。我已经看到了应该注入服务而不是实例化服务的观点,如果我错了,请纠正我,Jeffrey Palermo 表达的想法(http://jeffreypalermo.com/blog/the-onion-architecture-part-3/)是任何外层都应该能够直接调用任何内层。所以我的问题是

  1. 洋葱架构可以在没有 IOC 的情况下工作吗?如果可以,是否理想?
  2. 假设我们使用 IOC,如果 UI 不应该知道域服务的实际实现,我们是否应该将相同的原则应用于域模型本身,例如将模型注入 UI 而不是直接引用它们?

我理解为什么某些解决方案将 IOC 应用于域服务但直接在控制器中访问域模型。

0 投票
0 回答
538 浏览

domain-driven-design - 洋葱架构:应用层在哪里?

a) 如果 DDD 应用程序是使用 Onion 架构实现的,是否会Application layer驻留在 Onion 的Application Service layer

b) 在 Onion 中Object Services layer我们放置了提供基础结构行为的接口(例如ISendEmailor IRepository),但是 Onion 中的接口应该Application Service layer提供什么样的行为呢?

谢谢

0 投票
2 回答
170 浏览

interface - 非域服务接口

在学习领域驱动设计时,我一直在整理以下解决方案(请注意,此排序是字典顺序的,而不是依赖关系的表示):

在此处输入图像描述

以下是每个项目的概要:

Domain.Models: 域实体和值对象(例如Order

Domain.Interfaces: 域服务接口和存储库接口(例如IOrderServiceIOrderRepository

Domain.Services: 领域服务接口的具体实现(例如OrderService

Infrastructure.Data: 存储库接口的具体实现(例如OrderRepository

Infrastructure.DependencyResolution: 依赖注入解析。

问题

现在我想提供非域服务。一个示例是用于发送电子邮件的电子邮件网关。我为此创建了以下项目:

Infrastructure.Components: 非域服务的具体实现

问题

我会将此类非域服务的接口放在哪里(例如, an IEmailGateway)?

它需要可由Domain.Services项目访问(OrderService可能需要您发送通知),所以它会进入Domain.Interfaces吗?我会说不,因为发送电子邮件不是特定于域的活动。

0 投票
3 回答
10294 浏览

entity-framework - 用于更新整个聚合的通用存储库

我正在使用存储库模式来提供对我的聚合的访问和保存。

问题是更新由实体关系组成的聚合。

例如,采取OrderandOrderItem关系。聚合根Order管理自己的OrderItem集合。因此AnOrderRepository将负责更新整个聚合(不会有OrderItemRepository)。

使用 Entity Framework 6 处理数据持久性。

更新存储库方法(DbContext.SaveChanges()发生在别处):

在我上面的例子中,只有Order实体会被更新,而不是它的关联OrderItem集合。

我必须附加所有OrderItem实体吗?我怎么能一般地做到这一点?