- Revised the architecture documentation to include detailed diagrams and descriptions for the GoodGo Microservices Platform, enhancing clarity on system components and interactions. - Updated the .NET template documentation to reflect new naming conventions and project structures, ensuring consistency across services. - Added real-world examples and practical setup instructions for local development, including Traefik routing and environment variable configurations. - Enhanced the guide documentation with verification checklists and troubleshooting steps to support developers in deploying and managing services effectively.
473 lines
14 KiB
Markdown
473 lines
14 KiB
Markdown
# [Pattern Name] Pattern / Pattern [Tên Pattern]
|
|
|
|
> **EN**: Brief English description of when and why to use this pattern
|
|
> **VI**: Mô tả ngắn gọn bằng tiếng Việt về khi nào và tại sao sử dụng pattern này
|
|
|
|
## Pattern Overview / Tổng quan Pattern
|
|
|
|
```mermaid
|
|
graph LR
|
|
Input[Input/Request] --> Process[Pattern Process]
|
|
Process --> Output[Output/Result]
|
|
|
|
subgraph Pattern["Pattern Implementation"]
|
|
Process --> Step1[Step 1]
|
|
Step1 --> Step2[Step 2]
|
|
Step2 --> Step3[Step 3]
|
|
end
|
|
|
|
style Input fill:#e1f5ff
|
|
style Output fill:#d4edda
|
|
style Pattern fill:#f0e1ff
|
|
```
|
|
|
|
## When to Use / Khi nào sử dụng
|
|
|
|
### EN: Use this pattern when
|
|
|
|
- Scenario 1: Description of when this pattern is beneficial
|
|
- Scenario 2: Another use case
|
|
- Scenario 3: Additional context
|
|
|
|
**DO use this pattern for**:
|
|
- ✅ Use case 1
|
|
- ✅ Use case 2
|
|
|
|
**DON'T use this pattern for**:
|
|
- ❌ Anti-pattern 1
|
|
- ❌ Anti-pattern 2
|
|
|
|
### VI: Sử dụng pattern này khi
|
|
|
|
- Tình huống 1: Mô tả khi pattern này có lợi
|
|
- Tình huống 2: Trường hợp sử dụng khác
|
|
- Tình huống 3: Bối cảnh bổ sung
|
|
|
|
**NÊN sử dụng pattern này cho**:
|
|
- ✅ Trường hợp 1
|
|
- ✅ Trường hợp 2
|
|
|
|
**KHÔNG NÊN sử dụng pattern này cho**:
|
|
- ❌ Anti-pattern 1
|
|
- ❌ Anti-pattern 2
|
|
|
|
## Core Concepts / Khái niệm Cốt lõi
|
|
|
|
### EN: Key Principles
|
|
|
|
1. **Principle 1**: Description of the first core principle
|
|
2. **Principle 2**: Description of the second core principle
|
|
3. **Principle 3**: Description of the third core principle
|
|
|
|
### VI: Nguyên tắc Chính
|
|
|
|
1. **Nguyên tắc 1**: Mô tả nguyên tắc cốt lõi đầu tiên
|
|
2. **Nguyên tắc 2**: Mô tả nguyên tắc cốt lõi thứ hai
|
|
3. **Nguyên tắc 3**: Mô tả nguyên tắc cốt lõi thứ ba
|
|
|
|
## Implementation / Triển khai
|
|
|
|
### Basic Implementation / Triển khai Cơ bản
|
|
|
|
**EN**: Step-by-step explanation of how to implement this pattern.
|
|
|
|
**VI**: Giải thích từng bước về cách triển khai pattern này.
|
|
|
|
```typescript
|
|
// EN: Basic implementation example
|
|
// VI: Ví dụ triển khai cơ bản
|
|
|
|
/**
|
|
* EN: Pattern implementation class
|
|
* VI: Class triển khai pattern
|
|
*/
|
|
export class ExamplePattern {
|
|
/**
|
|
* EN: Constructor with dependencies
|
|
* VI: Constructor với các dependencies
|
|
*/
|
|
constructor(
|
|
private dependency1: Dependency1,
|
|
private dependency2: Dependency2
|
|
) {}
|
|
|
|
/**
|
|
* EN: Core method implementing the pattern
|
|
* VI: Phương thức cốt lõi triển khai pattern
|
|
*
|
|
* @param input - EN: Input data / VI: Dữ liệu đầu vào
|
|
* @returns EN: Processed result / VI: Kết quả đã xử lý
|
|
*/
|
|
async execute(input: InputType): Promise<OutputType> {
|
|
// EN: Step 1: Validate input
|
|
// VI: Bước 1: Validate đầu vào
|
|
this.validateInput(input);
|
|
|
|
// EN: Step 2: Process
|
|
// VI: Bước 2: Xử lý
|
|
const processed = await this.process(input);
|
|
|
|
// EN: Step 3: Return result
|
|
// VI: Bước 3: Trả về kết quả
|
|
return this.formatOutput(processed);
|
|
}
|
|
|
|
private validateInput(input: InputType): void {
|
|
// EN: Validation logic
|
|
// VI: Logic validation
|
|
if (!input) {
|
|
throw new Error('Input is required / Đầu vào là bắt buộc');
|
|
}
|
|
}
|
|
|
|
private async process(input: InputType): Promise<ProcessedType> {
|
|
// EN: Core business logic
|
|
// VI: Logic nghiệp vụ cốt lõi
|
|
return await this.dependency1.transform(input);
|
|
}
|
|
|
|
private formatOutput(processed: ProcessedType): OutputType {
|
|
// EN: Format for output
|
|
// VI: Định dạng cho đầu ra
|
|
return {
|
|
success: true,
|
|
data: processed,
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
**File Location / Vị trí File**:
|
|
- **Skill Template**: [`.agent/skills/skill-authoring/SKILL.md`](file:///Users/velikho/Desktop/WORKING/Base/.agent/skills/skill-authoring/SKILL.md)
|
|
- **Example Skills**: [`.agent/skills/`](file:///Users/velikho/Desktop/WORKING/Base/.agent/skills)
|
|
|
|
### Advanced Implementation / Triển khai Nâng cao
|
|
|
|
**EN**: More complex implementation with additional features like caching and error handling.
|
|
|
|
**VI**: Triển khai phức tạp hơn với các tính năng bổ sung như caching và xử lý lỗi.
|
|
|
|
```csharp
|
|
// EN: Advanced .NET implementation with caching
|
|
// VI: Triển khai .NET nâng cao với caching
|
|
|
|
public class CachedStorageProvider : IStorageProvider
|
|
{
|
|
private readonly IStorageProvider _innerProvider;
|
|
private readonly IDistributedCache _cache;
|
|
private readonly ILogger<CachedStorageProvider> _logger;
|
|
|
|
public async Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct)
|
|
{
|
|
try
|
|
{
|
|
// EN: Upload file
|
|
// VI: Upload file
|
|
var result = await _innerProvider.UploadFileAsync(fileStream, fileName, ct);
|
|
|
|
// EN: Invalidate cache
|
|
// VI: Vô hiệu hóa cache
|
|
await _cache.RemoveAsync($"file:{fileName}", ct);
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to upload file {FileName}", fileName);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Pattern Diagram / Sơ đồ Pattern
|
|
|
|
### Class Structure / Cấu trúc Class
|
|
|
|
```mermaid
|
|
classDiagram
|
|
class ExamplePattern {
|
|
-dependency1: Dependency1
|
|
-dependency2: Dependency2
|
|
+execute(input: InputType): OutputType
|
|
-validateInput(input: InputType): void
|
|
-process(input: InputType): ProcessedType
|
|
-formatOutput(processed: ProcessedType): OutputType
|
|
}
|
|
|
|
class AdvancedExamplePattern {
|
|
-cache: CacheService
|
|
-logger: Logger
|
|
+execute(input: InputType): OutputType
|
|
-getCacheKey(input: InputType): string
|
|
}
|
|
|
|
class Dependency1 {
|
|
+transform(input: InputType): ProcessedType
|
|
}
|
|
|
|
class CacheService {
|
|
+get(key: string): Promise~any~
|
|
+set(key: string, value: any, ttl: number): Promise~void~
|
|
}
|
|
|
|
ExamplePattern <|-- AdvancedExamplePattern
|
|
ExamplePattern --> Dependency1
|
|
AdvancedExamplePattern --> CacheService
|
|
```
|
|
|
|
### Sequence Flow / Luồng Tuần tự
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Client
|
|
participant Pattern as ExamplePattern
|
|
participant Dep1 as Dependency1
|
|
participant Cache as CacheService
|
|
|
|
Client->>Pattern: execute(input)
|
|
Pattern->>Cache: get(cacheKey)
|
|
Cache-->>Pattern: null (cache miss)
|
|
Pattern->>Pattern: validateInput(input)
|
|
Pattern->>Dep1: transform(input)
|
|
Dep1-->>Pattern: processed
|
|
Pattern->>Pattern: formatOutput(processed)
|
|
Pattern->>Cache: set(cacheKey, result, ttl)
|
|
Cache-->>Pattern: void
|
|
Pattern-->>Client: result
|
|
```
|
|
|
|
## Usage Examples / Ví dụ Sử dụng
|
|
|
|
### Example 1: Multi-Provider Storage Pattern (Real-World)
|
|
|
|
**EN**: Real implementation from Storage Service.
|
|
|
|
**VI**: Triển khai thực tế từ Storage Service.
|
|
|
|
```csharp
|
|
// Domain interface
|
|
public interface IStorageProvider
|
|
{
|
|
Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct);
|
|
Task<string> GeneratePresignedUrlAsync(string objectKey, int expiryMinutes, CancellationToken ct);
|
|
}
|
|
|
|
// Factory pattern
|
|
public class StorageProviderFactory
|
|
{
|
|
public IStorageProvider CreateProvider(string providerName)
|
|
{
|
|
return providerName?.ToLower() switch
|
|
{
|
|
"minio" => _serviceProvider.GetRequiredService<MinioStorageProvider>(),
|
|
"aliyun" => _serviceProvider.GetRequiredService<AliyunOssStorageProvider>(),
|
|
_ => throw new InvalidOperationException($"Unknown provider: {providerName}")
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
**File Reference**: [`services/storage-service-net/src/StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers)
|
|
|
|
---
|
|
|
|
### Example 2: CQRS with MediatR (Real-World)
|
|
|
|
**EN**: Command handler pattern from actual services.
|
|
|
|
**VI**: Pattern command handler từ các services thực tế.
|
|
|
|
```csharp
|
|
// Command
|
|
public record CreateFileCommand(string FileName, Stream FileStream, string UserId)
|
|
: IRequest<CreateFileCommandResult>;
|
|
|
|
// Handler
|
|
public class CreateFileCommandHandler : IRequestHandler<CreateFileCommand, CreateFileCommandResult>
|
|
{
|
|
private readonly IStorageProvider _storageProvider;
|
|
private readonly IFileRepository _fileRepository;
|
|
|
|
public async Task<CreateFileCommandResult> Handle(CreateFileCommand request, CancellationToken ct)
|
|
{
|
|
// Upload to storage
|
|
var objectKey = await _storageProvider.UploadFileAsync(
|
|
request.FileStream,
|
|
request.FileName,
|
|
ct
|
|
);
|
|
|
|
// Save metadata
|
|
var file = new File(request.FileName, objectKey, request.UserId);
|
|
await _fileRepository.AddAsync(file, ct);
|
|
|
|
return new CreateFileCommandResult(file.Id);
|
|
}
|
|
}
|
|
```
|
|
|
|
**File Reference**: See [CQRS with MediatR Skill](../skills/cqrs-mediatr.md)
|
|
|
|
## Best Practices / Thực hành Tốt nhất
|
|
|
|
### EN: Recommended Practices
|
|
|
|
1. **Practice 1**: Description of best practice with reasoning
|
|
2. **Practice 2**: Another important guideline
|
|
3. **Practice 3**: Additional recommendation
|
|
|
|
**Configuration / Cấu hình**:
|
|
```typescript
|
|
const config = {
|
|
timeout: 5000,
|
|
retries: 3,
|
|
cacheTime: 300, // 5 minutes
|
|
};
|
|
```
|
|
|
|
### VI: Thực hành Được đề xuất
|
|
|
|
1. **Nguyên tắc 1**: Mô tả best practice với lý do
|
|
2. **Nguyên tắc 2**: Hướng dẫn quan trọng khác
|
|
3. **Nguyên tắc 3**: Khuyến nghị bổ sung
|
|
|
|
## Common Mistakes / Lỗi Thường gặp
|
|
|
|
### EN: Mistakes to Avoid
|
|
|
|
#### Mistake 1 / Lỗi 1: [Description]
|
|
|
|
```typescript
|
|
// ❌ BAD: Incorrect implementation
|
|
const result = await pattern.execute(null); // Will throw error
|
|
```
|
|
|
|
```typescript
|
|
// ✅ GOOD: Correct implementation
|
|
if (input) {
|
|
const result = await pattern.execute(input);
|
|
}
|
|
```
|
|
|
|
**EN Why**: Explanation of why the first approach is bad and the second is good.
|
|
|
|
**VI Tại sao**: Giải thích tại sao cách tiếp cận đầu tiên là không tốt và cách thứ hai là tốt.
|
|
|
|
#### Mistake 2 / Lỗi 2: [Description]
|
|
|
|
(Repeat pattern for each common mistake)
|
|
|
|
## Performance Considerations / Cân nhắc Hiệu suất
|
|
|
|
**EN**: Performance characteristics and optimization tips.
|
|
|
|
**VI**: Đặc điểm hiệu suất và mẹo tối ưu hóa.
|
|
|
|
| Aspect / Khía cạnh | Impact / Tác động | Mitigation / Giảm thiểu |
|
|
|---------------------|-------------------|-------------------------|
|
|
| Memory usage / Sử dụng RAM | Medium / Trung bình | Use caching strategically / Sử dụng caching có chiến lược |
|
|
| CPU usage / Sử dụng CPU | Low / Thấp | N/A |
|
|
| I/O operations / Thao tác I/O | High / Cao | Implement connection pooling / Triển khai connection pooling |
|
|
|
|
## Testing / Kiểm thử
|
|
|
|
### Unit Test Example for .NET / Ví dụ Unit Test cho .NET
|
|
|
|
```csharp
|
|
// EN: Unit test for CQRS command handler
|
|
// VI: Unit test cho CQRS command handler
|
|
|
|
using Xunit;
|
|
using NSubstitute;
|
|
|
|
public class CreateFileCommandHandlerTests
|
|
{
|
|
private readonly IStorageProvider _storageProvider;
|
|
private readonly IFileRepository _fileRepository;
|
|
private readonly CreateFileCommandHandler _handler;
|
|
|
|
public CreateFileCommandHandlerTests()
|
|
{
|
|
_storageProvider = Substitute.For<IStorageProvider>();
|
|
_fileRepository = Substitute.For<IFileRepository>();
|
|
_handler = new CreateFileCommandHandler(_storageProvider, _fileRepository);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_ValidCommand_CreatesFileSuccessfully()
|
|
{
|
|
// Arrange
|
|
var command = new CreateFileCommand("test.txt", Stream.Null, "user-123");
|
|
_storageProvider.UploadFileAsync(Arg.Any<Stream>(), Arg.Any<string>(), Arg.Any<CancellationToken>())
|
|
.Returns("object-key-123");
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.NotEmpty(result.FileId);
|
|
await _fileRepository.Received(1).AddAsync(Arg.Any<File>(), Arg.Any<CancellationToken>());
|
|
}
|
|
}
|
|
```
|
|
|
|
**Reference**: See [Testing Patterns Skill](../skills/testing-patterns.md)
|
|
|
|
## Related Patterns / Patterns Liên quan
|
|
|
|
**EN**: Other patterns that complement or relate to this one.
|
|
|
|
**VI**: Các patterns khác bổ sung hoặc liên quan đến pattern này.
|
|
|
|
**GoodGo Skills**:
|
|
- [CQRS with MediatR](../skills/cqrs-mediatr.md) - EN: Command/Query separation / VI: Tách biệt Command/Query
|
|
- [Repository Pattern](../skills/repository-pattern.md) - EN: Data access abstraction / VI: Trừa tượng hóa truy cập dữ liệu
|
|
- [Domain-Driven Design](../skills/domain-driven-design.md) - EN: DDD tactical patterns / VI: Patterns chiến thuật DDD
|
|
- [Redis Caching](../skills/redis-caching.md) - EN: Distributed caching / VI: Caching phân tán
|
|
- [Error Handling](../skills/error-handling-patterns.md) - EN: Exception patterns / VI: Patterns exception
|
|
|
|
## Real-World Examples / Ví dụ Thực tế
|
|
|
|
**EN**: Examples of this pattern used in the GoodGo codebase.
|
|
|
|
**VI**: Ví dụ về pattern này được sử dụng trong codebase GoodGo.
|
|
|
|
### Storage Service - Multi-Provider Pattern
|
|
|
|
**File**: [`services/storage-service-net/src/StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers)
|
|
|
|
**Pattern**: Factory pattern for switching between MinIO and Aliyun OSS providers.
|
|
|
|
### IAM Service - RBAC Pattern
|
|
|
|
**File**: [`services/iam-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service-net)
|
|
|
|
**Pattern**: Role-Based Access Control implementation with permission caching.
|
|
|
|
## Additional Resources / Tài nguyên Bổ sung
|
|
|
|
### EN: Related Documentation
|
|
|
|
- [API Design Guide](../api-design.md) - How this pattern fits into API design
|
|
- [Error Handling](../error-handling-patterns.md) - Error handling for this pattern
|
|
- [Testing Guide](../testing-patterns.md) - Testing strategies
|
|
|
|
### VI: Tài liệu Liên quan
|
|
|
|
- [Hướng dẫn Thiết kế API](../api-design.md) - Pattern này khớp với thiết kế API như thế nào
|
|
- [Xử lý Lỗi](../error-handling-patterns.md) - Xử lý lỗi cho pattern này
|
|
- [Hướng dẫn Kiểm thử](../testing-patterns.md) - Chiến lược kiểm thử
|
|
|
|
### External Resources / Tài nguyên Bên ngoài
|
|
|
|
- [Design Patterns Book](https://example.com) - Classic reference
|
|
- [Blog Post](https://example.com) - Modern interpretation
|
|
|
|
---
|
|
|
|
**Complexity / Độ phức tạp**: Beginner/Intermediate/Advanced
|
|
**Category / Danh mục**: [Category Name]
|
|
**Authors / Tác giả**: VelikHo (hongochai10@icloud.com)
|