问题标签 [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 回答
549 浏览

c# - 应用程序服务方法中的工作单元/事务?

我了解如何使用实体框架来实现一个工作单元,并且仅在执行完整单元后才提交更改,但是我该如何更进一步呢?例如,以下需要全部发生在一个事务下

我不太确定如何确保发送电子邮件和将用户保存在数据库中都发生在一个事务中。任何意见是极大的赞赏

0 投票
4 回答
2187 浏览

c# - 设置域实体的身份

域中的所有实体都需要具有身份。通过继承自DomainEntity,我能够为类提供身份。

城市域实体(为便于阅读而精简):

DomainEntity 抽象类

首次创建新实体时,身份不存在。只有实体被持久化后,身份才会存在。因此,在创建实体的新实例时,Id不需要提供:

当使用 a 从持久性中读取城市时CityRepository,将使用第二个构造函数来填充标识属性:

我在这里遇到的问题是我提供了一个可以接受身份的构造函数。这打开了一个洞。我只希望在存储库层中设置身份,但客户端代码现在也可以开始设置Id值。是什么阻止了某人这样做:

如何提供在我的存储库中设置实体身份但从客户端代码中隐藏它的方法?也许我的设计有缺陷。我可以使用工厂来解决这个问题吗?

注意:我知道这不是 DDD 的完美实现,因为实体应该从一开始就具有身份。该Guid类型将帮助我解决这个问题,但不幸的是我没有那种奢侈。

0 投票
2 回答
2054 浏览

domain-driven-design - DDD:聚合设计 - 聚合之间的引用

我对如何设计聚合有疑问。

我有,CompanyCity实体。这些中的每一个都需要是其自身聚合的聚合根。和实体在整个系统中使用,并且被许多其他实体引用,因此它们不是值对象,也需要在许多不同的场景中访问。所以他们应该有存储库。A将具有诸如, , , ,之类的方法。ProvinceCountryCityProvinceCountryCityRepositoryFindById(int)GetAll()GetByProvince(Province)GetByCountry(Country)GetByName(string)

举个例子。一个Company实体与 a 相关联City,它属于 a ,Province它属于 a Country

聚合根

现在假设我们有一个公司列表页面,其中列出了一些公司及其城市、省和国家。

按 ID 引用

如果一个实体需要引用 a或City,他们将通过 ID 这样做(如 Vaughn Vernon 所建议)。 ProvinceCountry

为了从存储库中获取这些数据,我们需要调用 4 个不同的存储库,然后匹配数据以填充视图。

这是一种非常笨重且效率低下的方法,但显然是“正确”的方式?

引用引用

如果通过引用引用实体,则相同的查询将如下所示:

但据我了解,这些实体不能通过引用来引用,因为它们存在于不同的聚合中。

问题

我还能如何更好地设计这些聚合?

即使它们存在于不同的聚合中,我是否可以使用城市模型加载公司实体?我想这将很快打破聚合之间的界限。在更新聚合时处理事务一致性时也会造成混乱。

0 投票
2 回答
2095 浏览

domain-driven-design - 限界上下文实现和设计

假设我有两个有界上下文,即Shipping ContextBilling Context。这些上下文中的每一个都需要了解客户。

在数据级别,客户由CustomerTbl数据库中的表表示。此表包含描述客户的所有必要列。

中的列CustomerTbl(简化):

  • Name
  • PhysicalAddress
  • PaymentMethod

Shipping ContextNameand相关PhysicalAddress,而Billing ContextNameand相关PaymentMethod

运输上下文中,我对聚合进行了建模Recipient

  • RecipientName现在具有和的属性/值对象PhysicalAddress

计费上下文中,我对聚合进行了建模Payer

  • PayerName具有和的属性/值对象PaymentMethod

Recipient和聚合都Payer被上下文边界完全分开。他们也有自己的存储库。

问题:

  1. 使用同一个“数据库表”是否可以接受多个聚合(假设它们位于单独的有界上下文中)?

  2. 在更多有界的上下文中可能需要客户数据。这不意味着每个有界上下文都有许多聚合、存储库和工厂实现吗?代码会有一定程度的冗余。这不会影响可维护性吗?

  3. 跨聚合共享属性是否可以接受?一个例子是客户Name财产。这也意味着多余的验证码?

0 投票
1 回答
225 浏览

c# - DI 容器代码组织

我最近一直在使用依赖注入(Unity)来实现我的领域层和任何基础设施问题之间的低耦合。

我已经结束了很多Unity 容器代码。

一个小片段:

有没有更好的方法来组织这个?

我似乎无法在网上找到任何示例/文章/方向。

0 投票
2 回答
1354 浏览

architecture - 在 Onion 类型的架构中,实体是否应该跨越外层?

我一直在尝试理解这种新型架构,其名称可以是 Onion 架构、Clean 架构、端口和适配器等。

如果我采用端口和适配器的抽象,当我为特定端口调整我的应用程序时,我可以从我的应用程序内部给端口一个实体吗?还是我总是应该调整实体以适应端口?

例子:

假设我有一个客户实体。我有一个使用我的应用程序的 UI。我的 UI 通过适配器调用 getCustomerById(123)。反过来,我的适配器将调用我的应用程序,使用注入的存储库有效地检索客户,并将对其执行某种格式化和日志记录,一旦客户准备好,它就会返回到我的 UI。我的问题是,我的 Customer 对象按原样返回到我的 UI。这意味着我的 UI 引用了我的 Core 项目中的 Customer 类。然后我的 UI 继续使用该客户对象来做事,可能会更改它的名称等,并最终再次调用适配器来更新客户(客户)。

这可以吗?我的 UI 可以在我的应用程序核心内部使用 Customer 类吗?或者我应该改为让我的客户适应一个新的客户对象,比如 UICustomer 并让我的 UI 使用它,在适配器级别在客户和 UICustomer 之间来回映射?

0 投票
2 回答
1008 浏览

dependency-injection - Unity:未命名注册的隐式 ResolvedParameter

构造UserService函数有两个参数, aIUnitOfWork和 a IUserRepository

我正在使用命名注册来区分 的多个实例IUnitOfWork,因此在UserService使用 Unity 容器注册时,我需要使用 明确指定参数InjectionConstructor

new ResolvedParameter<IUserRepository>()可以省略吗?我希望 Unity 隐式推断此参数,因为不需要命名注册。 代码如下所示:

当我不需要使用InjectionConstructor.

0 投票
2 回答
1448 浏览

design-patterns - DDD 无状态服务和构造函数注入

在域驱动设计文献中,经常说域服务应该是无状态的。

我相信这是因为服务调用应该代表单个工作单元。不应该有多个服务方法会使用的任何服务状态。

我在我的服务架构中打破了这条规则,以便我可以构造函数注入服务中所需的所有相关存储库。例子:

为了让我在 上使用构造函数注入UserService,我需要有状态(属性),以便服务方法可以访问相关的存储库等。

尽管我希望将各个服务方法设计为独立的工作单元,但我不一定能阻止这种情况的发生。

我如何构建域服务以使其无状态? 这甚至有必要吗?

编辑:

领域驱动设计中的Eric Evans :解决软件核心的复杂性:

当域中的重要过程或转换不是实体或值对象的自然责任时,将操作添加到模型中作为声明为服务的独立接口。根据模型的语言定义接口,并确保操作名称是 UBIQUITOUS LANGUAGE 的一部分。使 SERVICE 无状态

Vaughn Vernon还在他的《实现领域驱动设计》一书中推荐了无状态服务。

0 投票
1 回答
176 浏览

c# - 领域服务的实现

我目前正在从事一个严重依赖外部组件的项目——主要是物理设备,如路由器、交换机、NVT 及其各自的通信协议(SNMP、Ping、RTSP ......)。我需要监视这些设备(它们是否在线?它们的状态如何?)并向它们发送操作消息。(启动该任务,启用此端口...)

不出所料,这是我真正需要的唯一域实体:

但我确实有很多服务。就像 ISnmpService、IPingService、IFtpService,... 现在我问自己:DDD 在这里如何帮助我?我必须在哪一层实现这些服务?这些甚至是“真正的”域服务吗?它们属于基础设施层还是在域层中实现服务是否可以?

以及这样的实现如何解决这样的问题:

0 投票
2 回答
1440 浏览

c# - 长时间运行的、有状态的“服务”在 DDD 中的什么位置?

在更多与行业或自动化相关的应用程序(主要依赖于他们必须管理的外部组件)中,您通常会遇到这样的情况,即域包含的模型不仅仅是对实际问题的抽象,还有表示of 和指向物理上存在于域之外的东西的指针。

例如,以这个代表网络设备的域实体为例:

应用程序可能需要根据外部组件在域内的表示来管理外部组件,而不是仅仅存储或验证此类实体或对实体更改采取行动。现在,DDD 甚至适用于这种情况吗?那些经理是域服务吗?

Eric Evans 在他著名的蓝皮书中描述了域服务需要是一个无状态 模型,实现从ubiquitos 语言中获取的方法,以完成实体或存储库无法自行处理的请求。但是如果服务需要有状态怎么办?

一个简单的例子:应用程序需要监视网络中配置的 IP 设备,以便通知域内的其他应用程序有关状态事件的信息。如果 IP 设备在应用程序中注册(例如存储在数据库中),“ping-service”会收到通知并开始监控设备。

然后其他组件可以处理这些状态事件,例如,如果设备离线,则停止通过其他协议与设备对话。

现在,这些组件是什么?起初我认为它们是域服务,因为它们服务于域的某种需求。但是,它们是有状态的,并且不具体代表ubiquitos 语言ping 服务的任务是ping域实体并报告其状态,但是ping 服务没有实现客户端允许 ping 的方法一个装置)。

它们是应用服务吗?这些组件在 DDD 模式中的什么位置?