项目地址
dbt
airflow
一、整洁架构概念
1.1 各个分层的功能
1. Domain核心部件
名称 |
解释 |
举例 |
Entities |
实体,具有唯一标识和生命周期的业务对象 |
Order , User , Product |
Value Objects |
值对象,无唯一标识,仅由值组成 |
Email , Money , Address |
Domain Events |
领域事件,表示领域内发生的某件重要事情 |
OrderPlaced , UserRegistered |
Domain Services |
不属于某个实体,但包含重要业务逻辑的服务 |
PaymentService , CurrencyConverter |
Interfaces |
接口,定义领域层依赖的外部功能(例如存储、邮件) |
IOrderRepository , INotificationService |
Exceptions |
业务异常,用于明确抛出领域问题 |
InsufficientBalanceException , InvalidEmailException |
Enums |
枚举类型,定义有限状态或类型集 |
OrderStatus , UserRole |
2. Application Layer
内容 |
解释 |
Orchestrates the Domain |
协调领域层 —— 应用层调用实体、值对象、领域服务等,把业务用例组织起来。 |
Contains business logic |
包含应用级别的业务逻辑 —— 不是业务规则本身,而是业务流程的组合,如"下订单 → 发送确认邮件"。 |
Defines the Use Cases |
定义用例 —— 每个用例通常表示用户或系统行为,如“创建事件”、“取消订单”、“生成报告”等。 |
Application services |
应用服务类 —— 是执行用例逻辑的容器,依赖领域模型(Entities、ValueObjects),协调外部接口(如仓储)。 |
CQRS with MediatR |
使用 CQRS + MediatR 模式来分离命令(Command)与查询(Query),提升结构清晰度、可测试性。 |
3. Infrastructure layer
- 所有的外部系统:
- Databases
- Messaging
- Email providers
- file upload/download
- Storage services
- Identity
- System lock
3. Presenetation layer
- 定义程序的入口
- Rest Api
- Middleware
- DI setup
1.2 项目数据库

二、Domain Layer
2.1 Apartments 实体
1. Current Value Obj
public record Currency
{
internal static readonly Currency None = new("");
public static readonly Currency Usd = new("USD");
public static readonly Currency Eur = new("EUR");
private Currency(string code)
{
Code = code;
}
public string Code {
get; init; }
public static Currency FromCode(string code)
{
return All.FirstOrDefault(c => c.Code == code) ??
throw new ApplicationException("The currency code is invalid");
}
public static readonly IReadOnlyCollection<Currency> All = new[]
{
Usd,
Eur
};
}
2. Money Value Obj
- 主要内容:
- 运算符重载,对money的类型进行了判断,不能随便相加
- 对 0, 空,的Money进行了定义
public record Money(decimal Amount, Currency Currency)
{
public static Money operator +(Money first, Money second)
{
if (first.Currency != second.Currency)
{
throw new InvalidOperationException("Currencies have to be equal");
}
return new Money(first.Amount + second.Amount, first.Currency);
}