---
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
