关于 modular-architecture
面向需要定义模块边界和实现模式的开发者,提供模块化单体设计技能,涵盖端口与适配器、模块通信、数据隔离及 MediatR。
主要功能
- 01按业务能力组织模块
- 02端口与适配器架构
- 03同步及事件式模块通信
- 04各模块独立隔离数据
- 05MediatR 事件模式
适用场景
- 01将限界上下文规划为应用模块
- 02降低模块间耦合
- 03分离模块持久化与数据架构
- 04使用 MediatR 连接内部事件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ melodic-software/ claude-code-plugins --skill modular-architecture安装后在 Claude Code 中输入/modular-architecture确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/data-patterns.mdmediatr-integration.mdmodule-communication.mdports-adapters-guide.md详细介绍
模块化架构
何时使用此技能
在以下情况下使用此技能:
- 设计模块化单体应用
- 定义模块之间的边界(限界上下文)
- 设置模块间通信模式
- 实现端口与适配器(六边形)架构
- 隔离各模块的数据库上下文
- 配置 MediatR 以处理内部领域事件
关键词: 模块化单体、模块、限界上下文、端口与适配器、六边形架构、模块通信、数据隔离、独立 DbContext、MediatR、领域事件、内部事件、模块边界
模块结构模式
核心原则
按**模块(业务能力)**组织代码,而非按层组织。每个模块都是一个自包含的垂直切片,拥有自己的:
- 领域实体和值对象
- 应用服务和处理程序
- 基础设施实现
- 用于外部通信的数据传输对象
标准模块布局
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, middleware
主要原则
- 禁止跨模块引用领域代码——模块不能引用彼此的 Core 项目
- 通过 DataTransfer 通信——使用 DTO 在模块之间传递数据
- 基础设施保持内部化——每个模块拥有自己的持久化实现
- 尽量精简共享内核——只有真正通用的概念才放入 Shared
端口与适配器(六边形)模式
六边形架构通过端口(接口)和适配器(实现)将业务逻辑与外部关注点分离。
详细指南: 参见 references/ports-adapters-guide.md
快速参考
┌─────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────┘
驱动端口: 应用对外提供的接口(由应用实现) 被驱动端口: 应用所需的接口(由适配器实现)
模块通信
模块必须在避免紧密耦合的前提下进行通信。主要有两种模式:
详细指南: 参见 references/module-communication.md
同步通信(DataTransfer)
适用于需要立即响应的查询操作:
// 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
}
}
异步通信(MediatR 领域事件)
适用于其他模块需要响应的状态变更:
// 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);
}
}
数据隔离模式
每个模块都应拥有自己的数据,以避免数据库层面的紧密耦合。
详细指南: 参见 references/data-patterns.md
每个模块使用独立的 DbContext
// 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; }
}
主要规则
- 模块之间不得设置外键——改用 ID 作为值对象
- 不得共享表——每个模块完全拥有自己的表
- 可以使用同一个数据库——为每个模块设置独立的架构或前缀
- 最终一致性——接受跨模块数据可能存在延迟
MediatR 集成
MediatR 为模块内 CQRS 和跨模块集成事件提供消息传递基础设施。
详细指南: 参见 references/mediatr-integration.md
注册模式
// 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;
}
}
事件类型
| 类型 | 范围 | 用途 |
|---|---|---|
| 领域事件 | 模块内部 | 聚合状态变更 |
| 集成事件 | 跨模块 | 通知其他模块发生的变更 |
与事件风暴的集成
此技能可与 event-storming 技能配合,用于发现限界上下文:
- 事件风暴发现限界上下文和事件
- 模块化架构将这些上下文实现为模块
- 事件成为 MediatR 集成事件
- 上下文边界成为模块边界
工作流:
Event Storming (discover "what")
↓
Bounded Contexts identified
↓
Modular Architecture (implement "where")
↓
Module structure created
↓
Fitness Functions (enforce boundaries)
适应度函数
使用 fitness-functions 技能来强制执行模块边界:
- 禁止跨模块引用领域代码
- DataTransfer 项目规则(仅允许 DTO)
- 基础设施隔离(不得泄漏实现细节)
快速入门清单
开始构建新的模块化单体时:
- 创建 Modules/ 目录结构
- 定义包含最少共享类型的 Shared.Kernel
- 创建各模块的项目(Core、Infrastructure、DataTransfer)
- 为每个模块配置单独的 DbContext
- 设置 MediatR 以处理领域事件/集成事件
- 添加架构测试以强制执行边界
- 在 DataTransfer 项目中记录模块 API
参考资料
references/ports-adapters-guide.md- 详细的六边形架构模式references/module-communication.md- 同步和异步通信模式references/data-patterns.md- 数据库隔离策略references/mediatr-integration.md- MediatR 配置和模式
版本历史
- v1.0.0(2025-12-22):首次发布
- 模块结构模式
- 端口和适配器概述
- 模块通信(同步/异步)
- 数据隔离模式
- MediatR 集成
- 事件风暴集成
最后更新
日期: 2025-12-22 模型: claude-opus-4-5-20251101