Skip to content

Commit

Permalink
Merge pull request #28 from netcorepal/dev
Browse files Browse the repository at this point in the history
add domain docs
  • Loading branch information
witskeeper authored May 12, 2024
2 parents 4291b81 + 7c32b42 commit 2e121f1
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 4 deletions.
39 changes: 35 additions & 4 deletions docs/content/domain/domain-entity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

## 介绍

领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。领域模型是DDD中的核心概念,它是对业务的抽象,是业务的核心。
领域模型是指在软件开发中,对特定领域或业务进行抽象和建模的表示方式。它描述了领域内的实体、概念、关系和行为,并提供了一种可交互和可执行的表示。领域模型通常是通过使用面向对象编程的概念来实现的,例如类、对象、属性和方法等。

在领域驱动设计(Domain-Driven Design,简称DDD)中,强调将领域模型作为核心组件来指导系统的设计与实现。DDD鼓励开发团队与领域专家密切合作,共同探索和理解领域的复杂性,并将这些理解转化为可维护和可扩展的软件系统。

领域驱动设计中的领域模型是通过对领域专家的知识进行建模而产生的。它不仅用于解决问题域的分析和设计,还可以在软件系统中实现业务逻辑。领域模型与领域驱动设计密切相关,因为领域模型是领域驱动设计的核心要素之一,帮助开发人员理解和应对复杂的业务场景,从而更好地构建高质量的软件系统。

## 定义领域模型

定义领域模型需要下列步骤:

1. 安装nuget包 `NetCorePal.Extensions.Domain`
1. 安装nuget包 `NetCorePal.Extensions.Domain.Abstractions`

```bash
dotnet add package NetCorePal.Extensions.Domain
dotnet add package NetCorePal.Extensions.Domain.Abstractions
```

2. 定义领域模型,需要:
Expand All @@ -35,7 +39,34 @@
public class User : Entity<UserId>, IAggregateRoot
{
protected User() { }
public string Name { get; set; }
public string Name { get; private set; }
public string Email { get; set; }
}
```
## 领域模型必须
- 领域模型的属性必须对外只读,内部可写(private set);
- 领域模型的属性变更必须通过模型实例方法;
- 领域模型必须有一个 `protected` 无参构造函数,用于支持EntityFrameworkCore框架在查询时构造领域模型实例;
- 领域模型必须继承 `IEntity``Entity<TKey>` 类;
- 领域模型的方法必须由`CommandHandler`调用;
## 领域模型可以
- 领域模型可以实现 `IAggregateRoot` 接口,以表示改模型是一个聚合根;
- 领域模型的属性和方法,用于描述领域内的实体、概念、关系和行为;
- 领域模型的构造函数,用于初始化领域模型的属性;
- 领域模型的事件,用于描述领域模型的状态变化;
- 领域模型的规则,用于验证领域模型的合法性;
## 领域模型不要
- 不要在领域模型中引用外部资源,如数据库连接、文件系统等;
- 不要在领域模型中处理与业务无关的逻辑,如日志记录、异常处理等;
- 不要在领域模型中直接调用外部服务,如Web API、消息队列等;
- 不要在领域模型中处理与业务无关的数据,如配置信息、环境变量等;
- 不要在领域模型中处理与业务无关的状态,如会话信息、用户信息等;
- 不要在领域模型中处理与业务无关的行为,如跟踪、监控等;
- 不要在领域模型中处理与业务无关的异常,如网络异常、数据库异常等;
- 不要在领域模型中处理与业务无关的事件,如定时任务、消息通知等;
46 changes: 46 additions & 0 deletions docs/content/domain/domain-event-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 领域事件处理

领域事件处理器是一个因`特定目的`而处理`领域事件`的处理逻辑,一个领域事件处理器应该仅针对一个目的来处理领域事件,针对同一`领域事件`的不同目的应该有不同的领域事件处理器。

## 定义领域事件处理器


1. 安装nuget包 `NetCorePal.Extensions.Domain.Abstractions`

```bash
dotnet add package NetCorePal.Extensions.Domain.Abstractions
```

2. 领域事件处理器是一个实现了`IDomainEventHandler<TDomainEvent>`接口的类,其中`TDomainEvent`是领域事件的类型。

下面是一个领域事件处理器的例子:

```csharp
public class OrderCreatedDomainEventHandler(IMediator mediator) : IDomainEventHandler<OrderCreatedDomainEvent>
{
public Task Handle(OrderCreatedDomainEvent notification, CancellationToken cancellationToken)
{
return mediator.Send(new DeliverGoodsCommand(notification.Order.Id), cancellationToken);
}
}
```

## 领域事件处理器必须

- 领域事件处理器必须是幂等的,即多次处理同一领域事件,结果应该是一致的。
- 领域事件处理器必须是无状态的,即不应该有任何状态,所有的状态应该通过领域事件传递。

**备注: 在我们的框架中,领域事件处理器是同步执行的,并且其调用的Command与触发领域事件的CommandHandler处于同一事务中**

## 领域事件处理器可以

- 领域事件处理器中可以使用`MediatR`框架来发送命令;
- 领域事件处理器中可以做一些简单的数据转换和信息查询;
- 领域事件处理器中可以调用外部服务来完成一些信息组织和验证;
- 领域事件处理器中可以发出集成事件来将事件传递给其它系统;

## 领域事件处理器不要

- 领域事件处理器中不要包含领域模型的操作,应该由CommandHandler操作领域模型并持久化;

**备注: 由于我们框架仅对`CommandHandler`做了事务管理,对于领域事件处理器中的操作框架不会做`SaveChangesAsync`,从而导致领域事件处理器中的操作不会被保存到数据库中**
45 changes: 45 additions & 0 deletions docs/content/domain/domain-event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 领域事件

领域事件是领域模型中的一个重要概念,它是领域模型中的一种通信机制,用于在领域模型之间传递消息。

领域事件仅包含描述事件发生时领域模型中的数据,不包含任何业务逻辑,业务规则和业务流程。

## 定义领域事件

1. 安装nuget包 `NetCorePal.Extensions.Domain.Abstractions`

```bash
dotnet add package NetCorePal.Extensions.Domain.Abstractions
```

2. 定义领域事件,需要:

+ 继承`NetCorePal.Extensions.Domain.IDomainEvent`接口;
+ 为领域事件定义一个空的构造函数,以支持序列化和反序列化;
+ 为领域事件定义一个公共的构造函数,用于初始化领域事件的属性;
+ 为领域事件定义一个公共的属性,用于描述事件发生时领域模型中的数据;

下面为一个示例:

```csharp
// 定义领域事件
using NetCorePal.Extensions.Domain;
namespace YourNamespace;
public record UserCreatedDomainEvent(User user) : IDomainEvent;
```

## 领域事件必须

- 领域事件必须由领域模型发出;
- 领域事件必须是不可变的;

## 领域事件可以

- 使用`record`关键字定义领域事件;

## 领域事件不要

- 不要包含业务逻辑
- 不要包含业务规则
- 不要包含业务流程
3 changes: 3 additions & 0 deletions docs/content/domain/domain-value-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 值类型

## 什么是值类型
11 changes: 11 additions & 0 deletions docs/content/integration-event.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 集成事件



## 集成事件必须

- 集成事件必须使用`DTO`对象,因为集成事件会在需要序列化和反序列化并在分布式系统中传递;

## 集成事件不要

- 集成事件不要使用领域模型

0 comments on commit 2e121f1

Please sign in to comment.