8.8 KiB
8.8 KiB
Design Document
Overview
本设计文档描述 HoneyBox 抽奖系统 .NET 8 Web API 项目基础架构的技术实现方案。采用四层架构设计,使用 Autofac 进行依赖注入,Mapster 进行对象映射,Serilog 进行日志记录,Redis 进行分布式缓存。
Architecture
┌─────────────────────────────────────────────────────────────┐
│ HoneyBox.Api │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Controllers │ │ Filters │ │ Middlewares │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────────┐
│ HoneyBox.Core │ │ HoneyBox.Model │
│ ┌─────────────────┐ │ │ ┌─────────────────────┐ │
│ │ Services │ │ │ │ Entities │ │
│ ├─────────────────┤ │ │ ├─────────────────────┤ │
│ │ Interfaces │ │ │ │ Models │ │
│ ├─────────────────┤ │ │ ├─────────────────────┤ │
│ │ Mappings │ │ │ │ Data │ │
│ └─────────────────┘ │ │ ├─────────────────────┤ │
└─────────────────────────┘ │ │ Base │ │
│ │ └─────────────────────┘ │
▼ └─────────────────────────────┘
┌─────────────────────────┐
│ HoneyBox.Infrastructure │
│ ┌─────────────────┐ │
│ │ Cache │ │
│ ├─────────────────┤ │
│ │ External │ │
│ ├─────────────────┤ │
│ │ Modules │ │
│ └─────────────────┘ │
└─────────────────────────┘
依赖关系
Api → Core, Model
Core → Model, Infrastructure
Infrastructure → 无依赖
Model → 无依赖
Components and Interfaces
HoneyBox.Model 组件
ApiResponse 基类
// Base/ApiResponse.cs
public class ApiResponse
{
public int Code { get; set; }
public string Msg { get; set; } = string.Empty;
public static ApiResponse Success(string msg = "success");
public static ApiResponse Fail(string msg, int code = -1);
}
public class ApiResponse<T> : ApiResponse
{
public T? Data { get; set; }
public static ApiResponse<T> Success(T data, string msg = "success");
public new static ApiResponse<T> Fail(string msg, int code = -1);
}
HoneyBoxDbContext
// Data/HoneyBoxDbContext.cs
public partial class HoneyBoxDbContext : DbContext
{
public HoneyBoxDbContext(DbContextOptions<HoneyBoxDbContext> options);
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Goods> Goods { get; set; }
public virtual DbSet<Order> Orders { get; set; }
// ... 其他 DbSet
}
HoneyBox.Infrastructure 组件
ICacheService 接口
// Cache/ICacheService.cs
public interface ICacheService
{
Task<T?> GetAsync<T>(string key);
Task SetAsync<T>(string key, T value, TimeSpan? expiry = null);
Task RemoveAsync(string key);
Task<bool> ExistsAsync(string key);
Task<bool> IsConnectedAsync();
}
RedisCacheService 实现
// Cache/RedisCacheService.cs
public class RedisCacheService : ICacheService
{
private readonly IDatabase _database;
private readonly ConnectionMultiplexer _connection;
public RedisCacheService(IConfiguration configuration);
public Task<T?> GetAsync<T>(string key);
public Task SetAsync<T>(string key, T value, TimeSpan? expiry = null);
public Task RemoveAsync(string key);
public Task<bool> ExistsAsync(string key);
public Task<bool> IsConnectedAsync();
}
Autofac 模块
// Modules/ServiceModule.cs
public class ServiceModule : Module
{
protected override void Load(ContainerBuilder builder);
}
// Modules/InfrastructureModule.cs
public class InfrastructureModule : Module
{
protected override void Load(ContainerBuilder builder);
}
HoneyBox.Core 组件
MappingConfig
// Mappings/MappingConfig.cs
public static class MappingConfig
{
public static void Configure();
}
HoneyBox.Api 组件
GlobalExceptionFilter
// Filters/GlobalExceptionFilter.cs
public class GlobalExceptionFilter : IExceptionFilter
{
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger);
public void OnException(ExceptionContext context);
}
HealthController
// Controllers/HealthController.cs
[ApiController]
[Route("api/[controller]")]
public class HealthController : ControllerBase
{
public HealthController(HoneyBoxDbContext dbContext, ICacheService cacheService);
[HttpGet]
public Task<ApiResponse<HealthCheckData>> GetHealth();
}
Data Models
健康检查响应模型
public class HealthCheckData
{
public string Status { get; set; } = string.Empty;
public string Database { get; set; } = string.Empty;
public string Redis { get; set; } = string.Empty;
public DateTime Timestamp { get; set; }
}
统一响应格式
所有 API 接口返回格式:
{
"code": 0,
"msg": "success",
"data": { ... }
}
Correctness Properties
A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.
由于本阶段主要是基础架构搭建,大部分验收标准是结构性检查(文件是否存在、配置是否正确),属于示例测试而非属性测试。以下是可以进行属性测试的场景:
Property 1: ApiResponse 格式一致性
For any API 响应,返回的 JSON 结构 SHALL 始终包含 code、msg 字段,当有数据时包含 data 字段 Validates: Requirements 6.4
Property 2: 缓存读写一致性
For any 缓存键值对,写入后立即读取 SHALL 返回相同的值 Validates: Requirements 3.5
Error Handling
全局异常处理策略
- 所有未捕获异常由 GlobalExceptionFilter 统一处理
- 异常信息记录到日志(Serilog)
- 返回统一格式的错误响应:
{ "code": 500, "msg": "服务器内部错误" } - 开发环境可返回详细错误信息,生产环境隐藏敏感信息
连接失败处理
- 数据库连接失败:健康检查返回 Database: "Disconnected"
- Redis 连接失败:健康检查返回 Redis: "Disconnected",但不影响应用启动
Testing Strategy
验证方式
由于本阶段是基础架构搭建,主要通过以下方式验证:
- 编译验证:
dotnet build确保项目能正常编译 - 运行验证:启动应用,访问 Swagger 文档
- 健康检查验证:调用
/api/health接口验证数据库和 Redis 连接 - 日志验证:检查控制台和日志文件输出
手动测试清单
- 解决方案能正常编译
- 应用能正常启动
- Swagger 文档可访问 (http://localhost:5000/swagger)
- 健康检查接口返回正确格式
- 日志输出到控制台
- 日志输出到文件 (logs/log-*.txt)