--- 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 Items { get; set; } } // ✅ ĐÚNG: Private setter, ReadOnly collection public class Order : Entity, IAggregateRoot { private readonly List _items = new(); public OrderStatus Status { get; private set; } public IReadOnlyCollection 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 { Task 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 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 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 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>> 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.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