# 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) | ## 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-net cd services/your-service-name-net # Đổi tên tất cả "MyService" thành "YourService" # Ví dụ: MyService → StorageService, UserService, PaymentService find . -type f -name "*.cs" -exec sed -i '' 's/MyService/YourService/g' {} + find . -type f -name "*.csproj" -exec sed -i '' 's/MyService/YourService/g' {} + find . -type f -name "*.sln" -exec sed -i '' 's/MyService/YourService/g' {} + ``` **Naming Convention**: - Service folder: `{service-name}-net` (ví dụ: `storage-service-net`, `iam-service-net`) - Projects: `{ServiceName}.API`, `{ServiceName}.Domain`, `{ServiceName}.Infrastructure` - DbContext: `{ServiceName}Context` (ví dụ: `StorageServiceContext`) - Namespace: `GoodGo.Services.{ServiceName}` (ví dụ: `GoodGo.Services.StorageService`) ### 2. Cấu Hình Môi Trường ```bash cp .env.example .env nano .env ``` ### 3. Chạy với Docker ```bash docker-compose up -d docker-compose logs -f myservice-api ``` ### 4. Chạy Local ```bash dotnet restore dotnet build dotnet run --project src/MyService.API ``` ## Cấu Trúc Dự Án ``` {service-name}-net/ # Ví dụ: storage-service-net ├── src/ │ ├── {ServiceName}.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 │ │ ├── Middlewares/ # Custom middlewares │ │ └── Program.cs # Điểm vào ứng dụng │ │ │ ├── {ServiceName}.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, IAggregateRoot) │ │ │ └── {ServiceName}.Infrastructure/ # Lớp Infrastructure │ ├── EntityConfigurations/ # Cấu hình EF Core (Fluent API) │ ├── Repositories/ # Triển khai repositories │ ├── Providers/ # External service providers (nếu có) │ ├── Services/ # Infrastructure services │ ├── Migrations/ # EF Core migrations │ └── {ServiceName}Context.cs # DbContext với Unit of Work │ ├── tests/ │ ├── {ServiceName}.UnitTests/ # Unit tests │ └── {ServiceName}.FunctionalTests/ # Integration tests │ ├── docs/ │ ├── en/ # English documentation │ │ ├── README.md │ │ └── ARCHITECTURE.md │ └── vi/ # Vietnamese documentation │ ├── README.md │ └── ARCHITECTURE.md │ ├── Dockerfile # Multi-stage Docker build ├── docker-compose.yml # Thiết lập phát triển local └── README.md # Service overview (bilingual) ``` **Examples thực tế**: - Storage Service: [`services/storage-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net) - IAM Service: [`services/iam-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service-net) - Chat Service: [`services/chat-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/chat-service-net) ## Kiến Trúc ```mermaid graph TB subgraph "Lớp API" C[Controllers] CMD[Commands] Q[Queries] B[Behaviors] V[Validations] end subgraph "Lớp Domain" AR[Aggregate Roots] E[Entities] VO[Value Objects] DE[Domain Events] end subgraph "Lớp Infrastructure" DB[(PostgreSQL)] R[Repositories] CTX[DbContext] end C --> CMD C --> Q CMD --> B --> V CMD --> AR Q --> R R --> CTX --> DB style C fill:#4a90d9,stroke:#2d5986,color:#fff style AR fill:#50c878,stroke:#2d8659,color:#fff style DB fill:#ff6b6b,stroke:#c0392b,color:#fff ``` ## Trách Nhiệm Các Lớp ### 1. Lớp Domain - **ZERO** phụ thuộc bên ngoài (ngoại trừ MediatR.Contracts) - Chỉ chứa các class POCO - Triển khai các tactical patterns của DDD | Thành phần | Mục Đích | |------------|----------| | **SeedWork** | Base classes: Entity, ValueObject, IAggregateRoot | | **AggregatesModel** | Aggregate roots với entities và value objects | | **Events** | Domain events cho giao tiếp cross-aggregate | | **Exceptions** | Domain exceptions | ### 2. Lớp Infrastructure - Truy cập database (EF Core) - Triển khai repositories - Tích hợp external services ### 3. Lớp API - Controllers để xử lý HTTP - Commands cho các thao tác ghi - Queries cho các thao tác đọc - MediatR behaviors cho cross-cutting concerns ## Pattern CQRS ### Commands (Thao Tác Ghi) ```csharp public record CreateSampleCommand(string Name, string? Description) : IRequest; public class CreateSampleCommandHandler : IRequestHandler { public async Task 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); } } ``` ### Pipeline MediatR ``` Request → LoggingBehavior → ValidatorBehavior → TransactionBehavior → Handler → Response ``` ## Các API Endpoints | 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 | ## Biến Môi Trường ### Required / Bắt buộc | Biến | Mô Tả | Mặc định | |------|-------|----------| | `ASPNETCORE_ENVIRONMENT` | Tên môi trường | `Development` | | `DATABASE_URL` | Kết nối Neon PostgreSQL | - | | `ConnectionStrings__DefaultConnection` | Connection string format chuẩn | - | ### Optional / Tùy chọn | Biến | Mô Tả | Mặc định | |------|-------|----------| | `REDIS_URL` | Kết nối Redis (cache) | - | | `RabbitMQ__Host` | RabbitMQ hostname | `localhost` | | `RabbitMQ__Port` | RabbitMQ port | `5672` | | `RabbitMQ__Username` | RabbitMQ username | `guest` | | `RabbitMQ__Password` | RabbitMQ password | `guest` | ### Inter-Service Communication | Biến | Mô Tả | Mặc định | |------|-------|----------| | `IamService__BaseUrl` | IAM Service URL | `http://iam-service-net:5001` | | `Services__InternalApiKey` | Shared secret cho service-to-service auth | - | ### Multi-Provider Pattern (Example: Storage Service) | Biến | Mô Tả | Mặc định | |------|-------|----------| | `Storage__Provider` | Provider: `minio` hoặc `aliyun` | `minio` | | `Storage__DefaultBucket` | Default bucket name | `storage` | | `Storage__MinIO__Endpoint` | MinIO endpoint | `localhost:9000` | | `Storage__MinIO__AccessKey` | MinIO access key | - | | `Storage__MinIO__SecretKey` | MinIO secret key | - | | `Storage__AliyunOSS__Endpoint` | Aliyun OSS endpoint | - | | `Storage__AliyunOSS__AccessKeyId` | Aliyun access key | - | | `Storage__AliyunOSS__AccessKeySecret` | Aliyun secret key | - | ## 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 ``` ## Triển Khai ### Docker Build ```bash docker build -t myservice:latest . docker run -p 5000:8080 --env-file .env myservice:latest ``` ### Kubernetes ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: myservice-api spec: replicas: 3 template: spec: containers: - name: api image: myservice:latest livenessProbe: httpGet: path: /health/live port: 8080 readinessProbe: httpGet: path: /health/ready port: 8080 ``` ## Patterns Nâng cao ### Multi-Provider Pattern **Sử dụng khi**: Service cần hỗ trợ nhiều external providers (storage, payment, SMS) **Example**: Storage Service với MinIO và Aliyun OSS ```csharp // Domain - Interface public interface IStorageProvider { Task UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct); Task DownloadFileAsync(string objectKey, CancellationToken ct); Task DeleteFileAsync(string objectKey, CancellationToken ct); Task GeneratePresignedUrlAsync(string objectKey, int expiryMinutes, CancellationToken ct); } // Infrastructure - MinIO Implementation public class MinioStorageProvider : IStorageProvider { private readonly MinioClient _client; // Implementation... } // Infrastructure - Aliyun OSS Implementation public class AliyunOssStorageProvider : IStorageProvider { private readonly OssClient _client; // Implementation... } // API - Provider Factory public class StorageProviderFactory { public IStorageProvider CreateProvider(IConfiguration config) { var provider = config["Storage:Provider"]; return provider?.ToLower() switch { "minio" => new MinioStorageProvider(config), "aliyun" => new AliyunOssStorageProvider(config), _ => throw new InvalidOperationException($"Unknown provider: {provider}") }; } } ``` **File Reference**: [`StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers) --- ### Inter-Service Authentication Pattern **Sử dụng khi**: Service cần validate JWT tokens với IAM Service ```csharp // Infrastructure - IAM Service Client public class IamServiceClient { private readonly HttpClient _httpClient; private readonly IConfiguration _config; public IamServiceClient(HttpClient httpClient, IConfiguration config) { _httpClient = httpClient; _config = config; _httpClient.BaseAddress = new Uri(_config["IamService:BaseUrl"]); } public async Task ValidateTokenAsync(string token, CancellationToken ct) { var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/auth/validate") { Headers = { { "Authorization", $"Bearer {token}" } } }; var response = await _httpClient.SendAsync(request, ct); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync(ct); } } // API - Middleware public class JwtValidationMiddleware { private readonly RequestDelegate _next; private readonly IamServiceClient _iamClient; public async Task InvokeAsync(HttpContext context) { var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); if (!string.IsNullOrEmpty(token)) { var userInfo = await _iamClient.ValidateTokenAsync(token, context.RequestAborted); context.Items["UserId"] = userInfo.UserId; } await _next(context); } } ``` --- ## 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 (System.Text.Json) - Hỗ trợ **LTS** 3 năm (đến tháng 11/2028) - **Entity Framework Core 10** với performance improvements ## Tích hợp với Platform ### Traefik Routing Thêm labels vào `docker-compose.yml`: ```yaml services: your-service-net: build: context: ../.. dockerfile: services/your-service-net/Dockerfile labels: - "traefik.enable=true" - "traefik.http.routers.your-service.rule=PathPrefix(`/api/v1/your-service`)" - "traefik.http.services.your-service.loadbalancer.server.port=8080" - "traefik.http.routers.your-service.middlewares=strip-prefix@docker" ``` ### Neon PostgreSQL Configuration ```json { "ConnectionStrings": { "DefaultConnection": "Host=ep-xxx.neon.tech;Database=your_service;Username=xxx;Password=xxx;SSL Mode=Require;Trust Server Certificate=true" } } ``` **Best Practices**: - Sử dụng connection pooling: `Pooling=true;Maximum Pool Size=100` - Enable SSL: `SSL Mode=Require` - Set command timeout: `Command Timeout=30` ### RabbitMQ Integration (thay vì Kafka) ```csharp // Domain Event public record FileUploadedEvent(string FileId, string UserId, long FileSize) : IDomainEvent; // Infrastructure - Event Publisher public class RabbitMqEventPublisher : IEventPublisher { private readonly IConnection _connection; private readonly IModel _channel; public async Task PublishAsync(T @event, CancellationToken ct) where T : IDomainEvent { var message = JsonSerializer.Serialize(@event); var body = Encoding.UTF8.GetBytes(message); _channel.BasicPublish( exchange: "domain_events", routingKey: typeof(T).Name, body: body ); } } ``` --- ## Tài Liệu Liên Quan ### Architecture - [System Design](../architecture/system-design.md) - Kiến trúc tổng thể GoodGo Platform - [Microservices Communication](../architecture/microservices-communication.md) - Patterns giao tiếp - [Caching Architecture](../architecture/caching-architecture.md) - Chiến lược Redis caching ### Skills - [CQRS with MediatR](../skills/cqrs-mediatr.md) - CQRS pattern implementation - [Repository Pattern](../skills/repository-pattern.md) - EF Core repository pattern - [Domain-Driven Design](../skills/domain-driven-design.md) - DDD tactical patterns - [Error Handling](../skills/error-handling-patterns.md) - Exception handling patterns ### Guides - [Local Development](../guides/local-development.md) - Setup môi trường dev - [Deployment](../guides/deployment.md) - Deploy lên Kubernetes ## Tài Nguyên Bổ sung ### Microsoft Official - [.NET 10 Documentation](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10) - [Entity Framework Core 10](https://docs.microsoft.com/en-us/ef/core/) - [ASP.NET Core 10](https://docs.microsoft.com/en-us/aspnet/core/) ### Architecture References - [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers) - Microservices reference architecture - [.NET Microservices Architecture Book](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/) ### Libraries - [MediatR](https://github.com/jbogard/MediatR) - CQRS implementation - [FluentValidation](https://docs.fluentvalidation.net/) - Validation library - [Polly](https://github.com/App-vNext/Polly) - Resilience and transient-fault-handling ### Tools - [EF Core Tools](https://docs.microsoft.com/en-us/ef/core/cli/dotnet) - Migrations và scaffolding - [Neon PostgreSQL](https://neon.tech/docs) - Serverless Postgres documentation --- **Last Updated**: 2026-01-14 **Template Version**: 2.0 **Maintained By**: GoodGo Architecture Team