# Template Microservice .NET 10

> Template microservice .NET 10 cấp doanh nghiệp theo các pattern DDD, CQRS và Clean Architecture.

## Tổng Quan

Template này cung cấp cấu trúc sẵn sàng production cho microservices .NET dựa trên kiến trúc tham chiếu eShopOnContainers với:

- **Domain-Driven Design (DDD)** - Aggregates, Entities, Value Objects, Domain Events
- **CQRS Pattern** - Tách biệt Commands (ghi) và Queries (đọc) với MediatR
- **Clean Architecture** - Phân tầng Domain, Infrastructure, API
- **EF Core 10** - PostgreSQL với connection resilience
- **FluentValidation** - Validation request
- **API Versioning** - Versioning theo URL segment
- **Health Checks** - Probes sẵn sàng cho Kubernetes
- **Structured Logging** - Serilog với console và Seq

## Yêu Cầu

| Yêu cầu | Phiên bản |
|---------|-----------|
| .NET SDK | 10.0.101+ |
| Docker | 24.0+ |
| PostgreSQL | 15+ (hoặc dùng Docker) |

```bash
# Kiểm tra phiên bản .NET
dotnet --version
# Kết quả nên là: 10.0.xxx
```

## Bắt Đầu Nhanh

### 1. Tạo Service Mới

```bash
# Sao chép template sang service mới
cp -r services/_template_dot_net services/your-service-name

# Di chuyển đến thư mục service
cd services/your-service-name

# Đổi tên tất cả "MyService" thành "YourService"
find . -type f -name "*.cs" -exec sed -i '' 's/MyService/YourService/g' {} +
find . -type f -name "*.csproj" -exec sed -i '' 's/MyService/YourService/g' {} +
```

### 2. Cấu Hình Môi Trường

```bash
# Sao chép template môi trường
cp .env.example .env

# Chỉnh sửa với cấu hình của bạn
nano .env
```

### 3. Chạy với Docker

```bash
# Khởi động tất cả services (API + PostgreSQL + Redis)
docker-compose up -d

# Xem logs
docker-compose logs -f myservice-api
```

### 4. Chạy Local

```bash
# Khôi phục dependencies
dotnet restore

# Build tất cả projects
dotnet build

# Chạy API
dotnet run --project src/MyService.API
```

## Cấu Trúc Dự Án

```
_template_dot_net/
├── src/
│   ├── MyService.API/              # Lớp Presentation (Controllers, CQRS)
│   │   ├── Controllers/            # Các API endpoints
│   │   ├── Application/            # Triển khai CQRS
│   │   │   ├── Commands/           # Thao tác ghi (MediatR)
│   │   │   ├── Queries/            # Thao tác đọc
│   │   │   ├── Behaviors/          # MediatR pipeline behaviors
│   │   │   └── Validations/        # FluentValidation validators
│   │   ├── Middleware/             # Custom middleware
│   │   └── Program.cs              # Điểm vào ứng dụng
│   │
│   ├── MyService.Domain/           # Lớp Domain (Business logic thuần túy)
│   │   ├── AggregatesModel/        # Aggregate roots và entities
│   │   ├── Events/                 # Domain events
│   │   ├── Exceptions/             # Domain exceptions
│   │   └── SeedWork/               # Base classes (Entity, ValueObject, etc.)
│   │
│   └── MyService.Infrastructure/   # Lớp Infrastructure (Truy cập dữ liệu)
│       ├── EntityConfigurations/   # Cấu hình EF Core Fluent API
│       ├── Repositories/           # Triển khai repositories
│       ├── Idempotency/            # Xử lý idempotency request
│       └── MyServiceContext.cs     # DbContext với Unit of Work
│
├── tests/
│   ├── MyService.UnitTests/        # Unit tests (Domain, Application)
│   └── MyService.FunctionalTests/  # Integration tests (API endpoints)
│
├── Dockerfile                      # Multi-stage Docker build
├── docker-compose.yml              # Thiết lập phát triển local
├── global.json                     # Pin phiên bản .NET SDK
└── Directory.Build.props           # Thuộc tính MSBuild chung
```

## Các Endpoint API

| Method | Endpoint | Mô Tả |
|--------|----------|-------|
| `GET` | `/api/v1/samples` | Lấy tất cả samples |
| `GET` | `/api/v1/samples/{id}` | Lấy sample theo ID |
| `POST` | `/api/v1/samples` | Tạo sample mới |
| `PUT` | `/api/v1/samples/{id}` | Cập nhật sample |
| `DELETE` | `/api/v1/samples/{id}` | Xóa sample |
| `PATCH` | `/api/v1/samples/{id}/status` | Thay đổi trạng thái |

### Health Endpoints

| Endpoint | Mục Đích |
|----------|----------|
| `/health` | Trạng thái health đầy đủ |
| `/health/live` | Kiểm tra sống |
| `/health/ready` | Kiểm tra sẵn sàng |

## Pattern CQRS

### Commands (Thao Tác Ghi)

```csharp
// Định nghĩa command
public record CreateSampleCommand(string Name, string? Description) 
    : IRequest<CreateSampleCommandResult>;

// Xử lý command
public class CreateSampleCommandHandler : IRequestHandler<CreateSampleCommand, CreateSampleCommandResult>
{
    public async Task<CreateSampleCommandResult> Handle(CreateSampleCommand request, CancellationToken ct)
    {
        var sample = new Sample(request.Name, request.Description);
        _repository.Add(sample);
        await _repository.UnitOfWork.SaveEntitiesAsync(ct);
        return new CreateSampleCommandResult(sample.Id);
    }
}
```

### Queries (Thao Tác Đọc)

```csharp
// Định nghĩa query
public record GetSampleQuery(Guid SampleId) : IRequest<SampleViewModel?>;
```

## Domain Model

### Aggregate Root

```csharp
public class Sample : Entity, IAggregateRoot
{
    public string Name => _name;
    public SampleStatus Status => _status;
    
    public Sample(string name, string? description) {
        // Validation business logic
        if (string.IsNullOrWhiteSpace(name))
            throw new SampleDomainException("Tên sample không được để trống");
        
        // Domain event
        AddDomainEvent(new SampleCreatedDomainEvent(this));
    }
    
    public void Activate() {
        if (_status != SampleStatus.Draft)
            throw new SampleDomainException("Chỉ sample draft mới có thể kích hoạt");
        // Chuyển đổi trạng thái
    }
}
```

## Kiểm Thử

```bash
# Chạy tất cả tests
dotnet test

# Chạy với coverage
dotnet test /p:CollectCoverage=true /p:CoverageReportFormat=cobertura

# Chạy project test cụ thể
dotnet test tests/MyService.UnitTests
```

## Cấu Hình

### Biến Môi Trường

| Biến | Mô Tả | Mặc định |
|------|-------|----------|
| `ASPNETCORE_ENVIRONMENT` | Tên môi trường | `Development` |
| `DATABASE_URL` | Connection string PostgreSQL | - |
| `REDIS_URL` | Connection string Redis | - |
| `JWT_SECRET` | Secret ký JWT (tối thiểu 32 ký tự) | - |

### appsettings.json

```json
{
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Database=myservice;Username=postgres;Password=postgres"
  },
  "Serilog": {
    "MinimumLevel": "Information"
  }
}
```

## Triển Khai

### Docker Build

```bash
# Build Docker image
docker build -t myservice:latest .

# Chạy container
docker run -p 5000:8080 --env-file .env myservice:latest
```

### Kubernetes

Xem [ARCHITECTURE.md](./ARCHITECTURE.md) để biết manifests triển khai Kubernetes.

## Có Gì Mới Trong .NET 10

- Tính năng ngôn ngữ **C# 14**
- Hỗ trợ **Native AOT** được cải thiện
- Hiệu suất **async/await** tốt hơn
- **JSON serialization** được nâng cao
- Cải thiện hiệu suất toàn diện
- Hỗ trợ **LTS** 3 năm (đến tháng 11/2028)

## Tài Nguyên

- [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers) - Kiến trúc tham chiếu
- [Tài liệu .NET 10](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10)
- [DDD với .NET](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/)
- [MediatR](https://github.com/jbogard/MediatR) - Thư viện CQRS
- [FluentValidation](https://docs.fluentvalidation.net/) - Thư viện validation

## Giấy Phép

Độc quyền - GoodGo Platform
