modular-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseModular Architecture
模块化架构
When to Use This Skill
何时使用该技能
Use this skill when you need to:
- Structure a modular monolith application
- Define boundaries between modules (bounded contexts)
- Set up inter-module communication patterns
- Implement ports and adapters (hexagonal) architecture
- Isolate database contexts between modules
- Configure MediatR for internal domain events
Keywords: modular monolith, modules, bounded contexts, ports and adapters, hexagonal architecture, module communication, data isolation, separate DbContext, MediatR, domain events, internal events, module boundaries
当你需要以下操作时,可使用本技能:
- 构建模块化单体应用
- 定义模块间的边界(限界上下文)
- 搭建模块间通信模式
- 实现端口与适配器(六边形)架构
- 在模块间隔离数据库上下文
- 为内部领域事件配置MediatR
关键词: 模块化单体、模块、限界上下文、端口与适配器、六边形架构、模块通信、数据隔离、独立DbContext、MediatR、领域事件、内部事件、模块边界
Module Structure Pattern
模块结构模式
Core Principle
核心原则
Organize code by modules (business capabilities), not layers. Each module is a self-contained vertical slice with its own:
- Domain entities and value objects
- Application services and handlers
- Infrastructure implementations
- Data transfer objects for external communication
按**模块(业务能力)**而非代码层来组织代码。每个模块是一个独立的垂直切片,拥有自己的:
- 领域实体与值对象
- 应用服务与处理器
- 基础设施实现
- 用于外部通信的数据传输对象
Standard Module Layout
标准模块布局
text
src/
├── Modules/
│ ├── Ordering/
│ │ ├── Ordering.Core/ # Domain + Application
│ │ │ ├── Domain/ # Entities, Value Objects, Events
│ │ │ ├── Application/ # Commands, Queries, Handlers
│ │ │ └── Ports/ # Interfaces (driven/driving)
│ │ ├── Ordering.Infrastructure/ # External dependencies
│ │ │ ├── Persistence/ # EF Core, DbContext
│ │ │ └── Adapters/ # External service implementations
│ │ └── Ordering.DataTransfer/ # DTOs for module-to-module communication
│ ├── Inventory/
│ │ ├── Inventory.Core/
│ │ ├── Inventory.Infrastructure/
│ │ └── Inventory.DataTransfer/
│ └── Shared/ # Truly shared kernel (minimal)
│ └── Shared.Kernel/ # Common value objects, interfaces
└── Host/ # Composition root, startup
└── Api/ # Controllers, middlewaretext
src/
├── Modules/
│ ├── Ordering/
│ │ ├── Ordering.Core/ # 领域层 + 应用层
│ │ │ ├── Domain/ # 实体、值对象、事件
│ │ │ ├── Application/ # 命令、查询、处理器
│ │ │ └── Ports/ # 接口(驱动/被驱动)
│ │ ├── Ordering.Infrastructure/ # 外部依赖实现
│ │ │ ├── Persistence/ # EF Core、DbContext
│ │ │ └── Adapters/ # 外部服务实现
│ │ └── Ordering.DataTransfer/ # 模块间通信的DTO
│ ├── Inventory/
│ │ ├── Inventory.Core/
│ │ ├── Inventory.Infrastructure/
│ │ └── Inventory.DataTransfer/
│ └── Shared/ # 真正的共享核心(最小化)
│ └── Shared.Kernel/ # 通用值对象、接口
└── Host/ # 组合根、启动项
└── Api/ # 控制器、中间件Key Principles
关键原则
- No cross-module domain references - Modules cannot reference each other's Core projects
- DataTransfer for communication - Use DTOs to pass data between modules
- Infrastructure stays internal - Each module owns its persistence
- Minimal shared kernel - Only truly universal concepts go in Shared
- 禁止跨模块领域引用 - 模块之间不能引用彼此的Core项目
- 通过DataTransfer通信 - 使用DTO在模块间传递数据
- 基础设施内部化 - 每个模块独立管理自己的持久化逻辑
- 最小化共享核心 - 只有真正通用的概念才放入Shared目录
Ports and Adapters (Hexagonal) Pattern
端口与适配器(六边形)模式
The hexagonal architecture separates business logic from external concerns through ports (interfaces) and adapters (implementations).
Detailed guide: See
references/ports-adapters-guide.md六边形架构通过端口(接口)和适配器(实现)将业务逻辑与外部依赖分离。
详细指南: 参见
references/ports-adapters-guide.mdQuick Reference
快速参考
text
┌─────────────────────────────────────────────────────────────┐
│ DRIVING SIDE (Primary) │
│ Controllers, CLI, Message Handlers, Tests │
│ │ │
│ ┌──────▼──────┐ │
│ │ PORTS │ (Input interfaces) │
│ │ IOrderService│ │
│ └──────┬──────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ APPLICATION │ │
│ │ (Use Cases/Handlers) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ DOMAIN │ │
│ │ (Entities, Value Objs) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ PORTS │ (Output interfaces) │
│ │IOrderRepository│ │
│ └──────┬──────┘ │
│ │ │
│ DRIVEN SIDE (Secondary) │
│ Databases, External APIs, File Systems, Queues │
└─────────────────────────────────────────────────────────────┘Driving Ports: Interfaces the application exposes (implemented by the application)
Driven Ports: Interfaces the application needs (implemented by adapters)
text
┌─────────────────────────────────────────────────────────────┐
│ 驱动端(主端) │
│ 控制器、CLI、消息处理器、测试 │
│ │ │
│ ┌──────▼──────┐ │
│ │ 端口 │ (输入接口) │
│ │ IOrderService│ │
│ └──────┬──────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ 应用层 │ │
│ │ (用例/处理器) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ 领域层 │ │
│ │ (实体、值对象) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ 端口 │ (输出接口) │
│ │IOrderRepository│ │
│ └──────┬──────┘ │
│ │ │
│ 被驱动端(次端) │
│ 数据库、外部API、文件系统、队列 │
└─────────────────────────────────────────────────────────────┘驱动端口: 应用对外暴露的接口(由应用层实现)
被驱动端口: 应用所需的外部接口(由适配器实现)
Module Communication
模块通信
Modules must communicate without creating tight coupling. Two primary patterns:
Detailed guide: See
references/module-communication.md模块通信必须避免产生紧耦合。主要有两种模式:
详细指南: 参见
references/module-communication.mdSynchronous Communication (DataTransfer)
同步通信(DataTransfer方式)
For query operations where immediate response is needed:
csharp
// In Inventory module - needs to check product availability
public class CheckStockHandler
{
private readonly IOrderingModuleApi _orderingApi;
public async Task<StockStatus> Handle(CheckStockQuery query)
{
// Get order info through DataTransfer DTO
var orderDto = await _orderingApi.GetOrderSummary(query.OrderId);
// orderDto is from Ordering.DataTransfer project
}
}适用于需要即时响应的查询操作:
csharp
// 在Inventory模块中 - 需要检查产品库存
public class CheckStockHandler
{
private readonly IOrderingModuleApi _orderingApi;
public async Task<StockStatus> Handle(CheckStockQuery query)
{
// 通过DataTransfer DTO获取订单信息
var orderDto = await _orderingApi.GetOrderSummary(query.OrderId);
// orderDto来自Ordering.DataTransfer项目
}
}Asynchronous Communication (MediatR Domain Events)
异步通信(MediatR领域事件)
For state changes that other modules need to react to:
csharp
// In Ordering module - publishes event after order is placed
public class PlaceOrderHandler
{
private readonly IMediator _mediator;
public async Task Handle(PlaceOrderCommand command)
{
// ... create order ...
// Publish integration event (handled by other modules)
await _mediator.Publish(new OrderPlacedIntegrationEvent(
order.Id, order.Items.Select(i => i.ProductId)));
}
}
// In Inventory module - handles the event
public class OrderPlacedHandler : INotificationHandler<OrderPlacedIntegrationEvent>
{
public async Task Handle(OrderPlacedIntegrationEvent notification, CancellationToken ct)
{
// Reserve inventory for the order
await _inventoryService.ReserveStock(notification.ProductIds);
}
}适用于其他模块需要响应的状态变更场景:
csharp
// 在Ordering模块中 - 下单完成后发布事件
public class PlaceOrderHandler
{
private readonly IMediator _mediator;
public async Task Handle(PlaceOrderCommand command)
{
// ... 创建订单 ...
// 发布集成事件(由其他模块处理)
await _mediator.Publish(new OrderPlacedIntegrationEvent(
order.Id, order.Items.Select(i => i.ProductId)));
}
}
// 在Inventory模块中 - 处理该事件
public class OrderPlacedHandler : INotificationHandler<OrderPlacedIntegrationEvent>
{
public async Task Handle(OrderPlacedIntegrationEvent notification, CancellationToken ct)
{
// 为订单预留库存
await _inventoryService.ReserveStock(notification.ProductIds);
}
}Data Isolation Patterns
数据隔离模式
Each module should own its data to prevent tight coupling at the database level.
Detailed guide: See
references/data-patterns.md每个模块应独立管理自己的数据,避免在数据库层面产生紧耦合。
详细指南: 参见
references/data-patterns.mdSeparate DbContext Per Module
每个模块独立使用DbContext
csharp
// Ordering module's DbContext
public class OrderingDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
// Only configure Ordering entities
builder.ApplyConfigurationsFromAssembly(typeof(OrderingDbContext).Assembly);
}
}
// Inventory module's DbContext
public class InventoryDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<StockLevel> StockLevels { get; set; }
}csharp
// Ordering模块的DbContext
public class OrderingDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
// 仅配置Ordering模块的实体
builder.ApplyConfigurationsFromAssembly(typeof(OrderingDbContext).Assembly);
}
}
// Inventory模块的DbContext
public class InventoryDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<StockLevel> StockLevels { get; set; }
}Key Rules
关键规则
- No foreign keys between modules - Use IDs as value objects instead
- No shared tables - Each module owns its tables completely
- Same database is acceptable - Separate schema/prefix per module
- Eventual consistency - Accept that cross-module data may be stale
- 模块间禁止外键关联 - 改用ID作为值对象
- 禁止共享数据表 - 每个模块完全独立拥有自己的表
- 可共用同一数据库 - 每个模块使用独立的数据库架构/表前缀
- 最终一致性 - 接受跨模块数据可能存在延迟的情况
MediatR Integration
MediatR集成
MediatR provides the messaging infrastructure for both in-module CQRS and cross-module integration events.
Detailed guide: See
references/mediatr-integration.mdMediatR为模块内的CQRS模式和跨模块的集成事件提供消息传递基础设施。
详细指南: 参见
references/mediatr-integration.mdRegistration Pattern
注册模式
csharp
// In each module's registration
public static class OrderingModule
{
public static IServiceCollection AddOrderingModule(this IServiceCollection services)
{
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(OrderingModule).Assembly));
services.AddScoped<IOrderingModuleApi, OrderingModuleApi>();
services.AddDbContext<OrderingDbContext>();
return services;
}
}csharp
// 在每个模块的注册代码中
public static class OrderingModule
{
public static IServiceCollection AddOrderingModule(this IServiceCollection services)
{
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(OrderingModule).Assembly));
services.AddScoped<IOrderingModuleApi, OrderingModuleApi>();
services.AddDbContext<OrderingDbContext>();
return services;
}
}Event Types
事件类型
| Type | Scope | Use Case |
|---|---|---|
| Domain Event | Within module | Aggregate state changes |
| Integration Event | Cross-module | Notify other modules of changes |
| 类型 | 范围 | 适用场景 |
|---|---|---|
| 领域事件 | 模块内部 | 聚合根状态变更 |
| 集成事件 | 跨模块 | 通知其他模块发生的变更 |
Integration with Event Storming
与事件风暴的集成
This skill works with the skill for bounded context discovery:
event-storming- Event Storming discovers bounded contexts and events
- Modular Architecture implements those contexts as modules
- Events become MediatR integration events
- Context boundaries become module boundaries
Workflow:
text
Event Storming (discover "what")
↓
Bounded Contexts identified
↓
Modular Architecture (implement "where")
↓
Module structure created
↓
Fitness Functions (enforce boundaries)本技能可与技能配合使用,用于限界上下文的发现:
event-storming- 事件风暴 发现限界上下文与事件
- 模块化架构 将这些上下文实现为模块
- 事件转化为MediatR集成事件
- 上下文边界成为模块边界
工作流程:
text
事件风暴(发现“是什么”)
↓
识别出限界上下文
↓
模块化架构(实现“放在哪里”)
↓
创建模块结构
↓
适配函数(强制执行边界)Fitness Functions
适配函数
Use the skill to enforce module boundaries:
fitness-functions- No cross-module domain references
- DataTransfer project rules (only DTOs)
- Infrastructure isolation (no leaking implementations)
使用技能来强制执行模块边界:
fitness-functions- 禁止跨模块领域引用
- DataTransfer项目规则(仅包含DTO)
- 基础设施隔离(禁止泄露实现细节)
Quick Start Checklist
快速启动检查清单
When starting a new modular monolith:
- Create Modules/ directory structure
- Define Shared.Kernel with minimal shared types
- Create per-module projects (Core, Infrastructure, DataTransfer)
- Configure separate DbContext per module
- Set up MediatR for domain/integration events
- Add architecture tests to enforce boundaries
- Document module APIs in DataTransfer projects
启动新的模块化单体应用时:
- 创建Modules/目录结构
- 定义包含最小共享类型的Shared.Kernel
- 为每个模块创建项目(Core、Infrastructure、DataTransfer)
- 为每个模块配置独立的DbContext
- 为领域/集成事件搭建MediatR
- 添加架构测试以强制执行边界
- 在DataTransfer项目中记录模块API
References
参考资料
- - Detailed hexagonal architecture patterns
references/ports-adapters-guide.md - - Sync and async communication patterns
references/module-communication.md - - Database isolation strategies
references/data-patterns.md - - MediatR configuration and patterns
references/mediatr-integration.md
- - 六边形架构模式详细指南
references/ports-adapters-guide.md - - 同步与异步通信模式
references/module-communication.md - - 数据库隔离策略
references/data-patterns.md - - MediatR配置与模式
references/mediatr-integration.md
Version History
版本历史
- v1.0.0 (2025-12-22): Initial release
- Module structure patterns
- Ports and adapters overview
- Module communication (sync/async)
- Data isolation patterns
- MediatR integration
- Event storming integration
- v1.0.0(2025-12-22):初始版本
- 模块结构模式
- 端口与适配器概述
- 模块通信(同步/异步)
- 数据隔离模式
- MediatR集成
- 事件风暴集成
Last Updated
最后更新
Date: 2025-12-22
Model: claude-opus-4-5-20251101
日期: 2025-12-22
模型: claude-opus-4-5-20251101