Migrate
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
---
|
||||
name: dotnet-microservice-workflow
|
||||
description: Workflow phát triển .NET Microservices theo 4 lớp (Domain → Infrastructure → Application → API). Use for creating new features, new services, hoặc khi cần structured approach theo DDD + CQRS + Clean Architecture.
|
||||
compatibility: ".NET 10+, EF Core 9+, MediatR 12+"
|
||||
metadata:
|
||||
author: Velik Ho
|
||||
version: "1.0"
|
||||
references: "eShopOnContainers, .NET Microservices Architecture Guide"
|
||||
---
|
||||
|
||||
# .NET Microservice Development Workflow
|
||||
|
||||
Quy trình 4 giai đoạn để phát triển features hoặc services theo chuẩn DDD + CQRS + Clean Architecture.
|
||||
|
||||
## When to Use This Skill / Khi Nào Sử Dụng
|
||||
|
||||
Use this workflow when:
|
||||
- Creating a new domain feature / Tạo feature mới trong domain
|
||||
- Building a new microservice from scratch / Xây service mới từ đầu
|
||||
- Refactoring existing code to DDD / Refactor code sang DDD
|
||||
- Need structured approach / Cần approach có cấu trúc
|
||||
|
||||
**DO NOT use when:**
|
||||
- Simple CRUD operations / Các thao tác CRUD đơn giản
|
||||
- Prototyping / Làm prototype nhanh
|
||||
- Small utilities / Các utility nhỏ
|
||||
|
||||
## Overview / Tổng Quan
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ WORKFLOW 4 GIAI ĐOẠN │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────────┐ │
|
||||
│ │ PHASE 1 │────►│ PHASE 2 │ │
|
||||
│ │ DOMAIN │ │ INFRASTRUCTURE │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ - Aggregates│ │ - EF Config │ │
|
||||
│ │ - Entities │ │ - Repositories │ │
|
||||
│ │ - V.Objects │ │ - Migrations │ │
|
||||
│ │ - D.Events │ │ - Idempotency │ │
|
||||
│ └─────────────┘ └────────┬────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────────┐ │
|
||||
│ │ PHASE 4 │◄────│ PHASE 3 │ │
|
||||
│ │ API │ │ APPLICATION │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ - Controls │ │ - Commands │ │
|
||||
│ │ - Health │ │ - Queries │ │
|
||||
│ │ - Resilien. │ │ - Handlers │ │
|
||||
│ │ - OpenAPI │ │ - Behaviors │ │
|
||||
│ └─────────────┘ └─────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Phase 1: Domain Layer / Lớp Nghiệp Vụ
|
||||
|
||||
**Goal**: Thiết kế Domain Model sạch, không phụ thuộc framework
|
||||
|
||||
**Key Skill**: [Domain-Driven Design](../domain-driven-design/SKILL.md)
|
||||
|
||||
### Checklist
|
||||
|
||||
1. **Xác định Aggregate Root**
|
||||
- Mọi thay đổi dữ liệu phải đi qua Aggregate Root
|
||||
- Đảm bảo tính nhất quán (Consistency)
|
||||
|
||||
2. **Thiết kế Entities**
|
||||
- Properties với `private set`
|
||||
- Thao tác qua methods có ý nghĩa nghiệp vụ
|
||||
- Backing fields cho collections
|
||||
|
||||
3. **Tạo Value Objects**
|
||||
- Immutable (bất biến)
|
||||
- Equality by all properties
|
||||
|
||||
4. **Định nghĩa Domain Events**
|
||||
- Implement `IDomainEvent`
|
||||
- Raise trong aggregate methods
|
||||
|
||||
5. **Unit Tests**
|
||||
- Test business rules trong domain
|
||||
|
||||
### Rules
|
||||
|
||||
```csharp
|
||||
// ❌ SAI: Public setter, expose mutable collection
|
||||
public class Order
|
||||
{
|
||||
public OrderStatus Status { get; set; }
|
||||
public List<OrderItem> Items { get; set; }
|
||||
}
|
||||
|
||||
// ✅ ĐÚNG: Private setter, ReadOnly collection
|
||||
public class Order : Entity, IAggregateRoot
|
||||
{
|
||||
private readonly List<OrderItem> _items = new();
|
||||
|
||||
public OrderStatus Status { get; private set; }
|
||||
public IReadOnlyCollection<OrderItem> Items => _items.AsReadOnly();
|
||||
|
||||
public void AddItem(Guid productId, int quantity, decimal price)
|
||||
{
|
||||
if (Status != OrderStatus.Draft)
|
||||
throw new DomainException("Cannot modify non-draft order");
|
||||
_items.Add(new OrderItem(productId, quantity, price));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Infrastructure Layer / Lớp Hạ Tầng
|
||||
|
||||
**Goal**: Triển khai persistence mà không làm ô nhiễm Domain
|
||||
|
||||
**Key Skill**: [Repository Pattern](../repository-pattern/SKILL.md)
|
||||
|
||||
### Checklist
|
||||
|
||||
1. **EF Core Configurations**
|
||||
- Sử dụng `IEntityTypeConfiguration`
|
||||
- Fluent API, không Data Annotations
|
||||
|
||||
2. **Repository cho Aggregate Root**
|
||||
- Chỉ 1 repository per aggregate
|
||||
- Implement `IUnitOfWork`
|
||||
|
||||
3. **Database Migrations**
|
||||
- Tạo và apply migrations
|
||||
|
||||
4. **Idempotency (Optional)**
|
||||
- `IdentifiedCommand` cho critical operations
|
||||
|
||||
### Rules
|
||||
|
||||
```csharp
|
||||
// ❌ SAI: Repository cho từng table
|
||||
public interface IOrderItemRepository { }
|
||||
public interface IOrderPaymentRepository { }
|
||||
|
||||
// ✅ ĐÚNG: Chỉ repository cho Aggregate Root
|
||||
public interface IOrderRepository : IRepository<Order>
|
||||
{
|
||||
Task<Order?> GetWithItemsAsync(Guid id, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Application Layer (CQRS)
|
||||
|
||||
**Goal**: Tách biệt luồng Đọc (Query) và Ghi (Command)
|
||||
|
||||
**Key Skill**: [CQRS MediatR](../cqrs-mediatr/SKILL.md)
|
||||
|
||||
### Checklist
|
||||
|
||||
1. **Commands**
|
||||
- Tạo Command record
|
||||
- Implement CommandHandler
|
||||
- Gọi domain methods, save qua Repository
|
||||
|
||||
2. **Queries**
|
||||
- Bypass Domain Model
|
||||
- Sử dụng Dapper cho performance
|
||||
- Return lightweight DTOs
|
||||
|
||||
3. **Validators**
|
||||
- FluentValidation cho input validation
|
||||
- Register trong Pipeline Behaviors
|
||||
|
||||
4. **Pipeline Behaviors**
|
||||
- LoggingBehavior
|
||||
- ValidationBehavior
|
||||
- TransactionBehavior (optional)
|
||||
|
||||
### Rules
|
||||
|
||||
```csharp
|
||||
// ❌ SAI: Business logic trong Handler
|
||||
public async Task<OrderResult> Handle(CreateOrderCommand cmd, CancellationToken ct)
|
||||
{
|
||||
if (cmd.Items.Count == 0)
|
||||
throw new Exception("Empty order"); // Logic nên ở Domain!
|
||||
}
|
||||
|
||||
// ✅ ĐÚNG: Delegate logic cho Domain
|
||||
public async Task<OrderResult> Handle(CreateOrderCommand cmd, CancellationToken ct)
|
||||
{
|
||||
var order = new Order(cmd.UserId, cmd.Address);
|
||||
foreach (var item in cmd.Items)
|
||||
order.AddItem(item.ProductId, item.Quantity, item.Price); // Domain validates
|
||||
|
||||
await _repository.AddAsync(order, ct);
|
||||
await _repository.UnitOfWork.SaveChangesAsync(ct);
|
||||
return new OrderResult(order.Id);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: API Layer / Lớp API
|
||||
|
||||
**Goal**: Expose API đúng chuẩn với cross-cutting concerns
|
||||
|
||||
**Key Skills**:
|
||||
- [API Design](../api-design/SKILL.md)
|
||||
- [Error Handling](../error-handling-patterns/SKILL.md)
|
||||
- [Inter-Service Communication](../inter-service-communication/SKILL.md)
|
||||
|
||||
### Checklist
|
||||
|
||||
1. **Slim Controllers**
|
||||
- Chỉ nhận request, gọi MediatR
|
||||
- ApiResponse wrapper
|
||||
|
||||
2. **Health Checks**
|
||||
- Endpoint `/hc` hoặc `/health`
|
||||
- Check DB, Redis, RabbitMQ connections
|
||||
|
||||
3. **Resilience (Polly)**
|
||||
- Retry với Exponential Backoff
|
||||
- Circuit Breaker cho external calls
|
||||
|
||||
4. **OpenAPI Documentation**
|
||||
- SwaggerOperation attributes
|
||||
- SwaggerResponse cho từng status code
|
||||
|
||||
5. **DI Registration**
|
||||
- Register MediatR, Validators
|
||||
- Register Repositories, Services
|
||||
|
||||
### Rules
|
||||
|
||||
```csharp
|
||||
// ❌ SAI: Fat controller với logic
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateOrder(CreateOrderRequest request)
|
||||
{
|
||||
var order = new Order(request.UserId, request.Address);
|
||||
foreach (var item in request.Items)
|
||||
order.AddItem(item.ProductId, item.Quantity, item.Price);
|
||||
await _repository.AddAsync(order);
|
||||
await _context.SaveChangesAsync();
|
||||
return Ok(order.Id);
|
||||
}
|
||||
|
||||
// ✅ ĐÚNG: Slim controller
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<ApiResponse<OrderResult>>> CreateOrder(
|
||||
CreateOrderRequest request,
|
||||
CancellationToken ct)
|
||||
{
|
||||
var command = request.ToCommand(GetUserId());
|
||||
var result = await _mediator.Send(command, ct);
|
||||
return CreatedAtAction(nameof(GetOrder), new { id = result.OrderId },
|
||||
ApiResponse<OrderResult>.Ok(result));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Mistakes / Lỗi Thường Gặp
|
||||
|
||||
| Mistake | Problem | Solution |
|
||||
|---------|---------|----------|
|
||||
| Skip Domain Layer | Anemic model, logic scattered | Always start with Domain |
|
||||
| Logic in Handler | Hard to test, duplicate | Move to Domain methods |
|
||||
| Fat Controllers | Violates SRP | Use MediatR pattern |
|
||||
| Query via EF Core | N+1, over-fetching | Use Dapper for reads |
|
||||
| Repository per table | Breaks aggregate rules | Only for Aggregate Root |
|
||||
|
||||
## Quick Reference / Tham Chiếu Nhanh
|
||||
|
||||
| Phase | Layer | Location | Key Patterns |
|
||||
|-------|-------|----------|--------------|
|
||||
| 1 | Domain | `ServiceName.Domain/` | Aggregate, Entity, VO |
|
||||
| 2 | Infrastructure | `ServiceName.Infrastructure/` | Repository, UoW, EF |
|
||||
| 3 | Application | `ServiceName.API/Application/` | Command, Query, Handler |
|
||||
| 4 | API | `ServiceName.API/Controllers/` | Controller, HealthCheck |
|
||||
|
||||
## Resources / Tài Nguyên
|
||||
|
||||
- [Detailed Checklist](./references/checklist.md) - Checklist từng giai đoạn
|
||||
- [Technical Reference](./references/REFERENCE.md) - Chi tiết kỹ thuật
|
||||
- [Domain-Driven Design](../domain-driven-design/SKILL.md) - DDD patterns
|
||||
- [Repository Pattern](../repository-pattern/SKILL.md) - Data access
|
||||
- [CQRS MediatR](../cqrs-mediatr/SKILL.md) - Command/Query handlers
|
||||
- [API Design](../api-design/SKILL.md) - Controller patterns
|
||||
- [Error Handling](../error-handling-patterns/SKILL.md) - Exception handling
|
||||
- [Testing Patterns](../testing-patterns/SKILL.md) - Unit/Integration tests
|
||||
- [Project Rules](../project-rules/SKILL.md) - Coding standards
|
||||
Reference in New Issue
Block a user