docs(zh-CN): sync Chinese docs with latest upstream changes

This commit is contained in:
neo
2026-03-21 12:55:58 +08:00
parent 0af0fbf40b
commit e73c2ffa34
85 changed files with 11028 additions and 747 deletions

View File

@@ -0,0 +1,73 @@
---
paths:
- "**/*.cs"
- "**/*.csx"
---
# C# 编码风格
> 本文档扩展了 [common/coding-style.md](../common/coding-style.md) 中关于 C# 的特定内容。
## 标准
* 遵循当前的 .NET 约定并启用可为空引用类型
* 在公共和内部 API 上优先使用显式访问修饰符
* 保持文件与其定义的主要类型对齐
## 类型与模型
* 对于不可变的值类型模型,优先使用 `record``record struct`
* 对于具有标识和生命周期的实体或类型,使用 `class`
* 对于服务边界和抽象,使用 `interface`
* 避免在应用程序代码中使用 `dynamic`;优先使用泛型或显式模型
```csharp
public sealed record UserDto(Guid Id, string Email);
public interface IUserRepository
{
Task<UserDto?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
}
```
## 不可变性
* 对于共享状态,优先使用 `init` 设置器、构造函数参数和不可变集合
* 在生成更新状态时,不要原地修改输入模型
```csharp
public sealed record UserProfile(string Name, string Email);
public static UserProfile Rename(UserProfile profile, string name) =>
profile with { Name = name };
```
## 异步与错误处理
* 优先使用 `async`/`await`,而非阻塞调用如 `.Result``.Wait()`
* 通过公共异步 API 传递 `CancellationToken`
* 抛出特定异常并使用结构化属性进行日志记录
```csharp
public async Task<Order> LoadOrderAsync(
Guid orderId,
CancellationToken cancellationToken)
{
try
{
return await repository.FindAsync(orderId, cancellationToken)
?? throw new InvalidOperationException($"Order {orderId} was not found.");
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to load order {OrderId}", orderId);
throw;
}
}
```
## 格式化
* 使用 `dotnet format` 进行格式化和分析器修复
* 保持 `using` 指令有序,并移除未使用的导入
* 仅当表达式体成员保持可读性时才优先使用

View File

@@ -0,0 +1,26 @@
---
paths:
- "**/*.cs"
- "**/*.csx"
- "**/*.csproj"
- "**/*.sln"
- "**/Directory.Build.props"
- "**/Directory.Build.targets"
---
# C# 钩子
> 本文档基于 [common/hooks.md](../common/hooks.md) 扩展了 C# 相关的具体内容。
## PostToolUse 钩子
`~/.claude/settings.json` 中配置:
* **dotnet format**:自动格式化编辑过的 C# 文件并应用分析器修复
* **dotnet build**:验证编辑后解决方案或项目是否仍能编译
* **dotnet test --no-build**:在行为更改后重新运行最近相关的测试项目
## Stop 钩子
* 在结束涉及广泛 C# 更改的会话前,运行一次最终的 `dotnet build`
*`appsettings*.json` 文件被修改时发出警告,以防敏感信息被提交

View File

@@ -0,0 +1,51 @@
---
paths:
- "**/*.cs"
- "**/*.csx"
---
# C# 模式
> 本文档在 [common/patterns.md](../common/patterns.md) 的基础上扩展了 C# 相关内容。
## API 响应模式
```csharp
public sealed record ApiResponse<T>(
bool Success,
T? Data = default,
string? Error = null,
object? Meta = null);
```
## 仓储模式
```csharp
public interface IRepository<T>
{
Task<IReadOnlyList<T>> FindAllAsync(CancellationToken cancellationToken);
Task<T?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
Task<T> CreateAsync(T entity, CancellationToken cancellationToken);
Task<T> UpdateAsync(T entity, CancellationToken cancellationToken);
Task DeleteAsync(Guid id, CancellationToken cancellationToken);
}
```
## 选项模式
使用强类型选项进行配置,而不是在整个代码库中读取原始字符串。
```csharp
public sealed class PaymentsOptions
{
public const string SectionName = "Payments";
public required string BaseUrl { get; init; }
public required string ApiKeySecretName { get; init; }
}
```
## 依赖注入
* 在服务边界上依赖于接口
* 保持构造函数专注;如果某个服务需要太多依赖项,请拆分其职责
* 有意识地注册生命周期:无状态/共享服务使用单例,请求数据使用作用域,轻量级纯工作者使用瞬时

View File

@@ -0,0 +1,59 @@
---
paths:
- "**/*.cs"
- "**/*.csx"
- "**/*.csproj"
- "**/appsettings*.json"
---
# C# 安全性
> 本文档在 [common/security.md](../common/security.md) 的基础上补充了 C# 特有的内容。
## 密钥管理
* 切勿在源代码中硬编码 API 密钥、令牌或连接字符串
* 在本地开发环境中使用环境变量或用户密钥,在生产环境中使用密钥管理器
* 确保 `appsettings.*.json` 中不包含真实的凭证信息
```csharp
// BAD
const string ApiKey = "sk-live-123";
// GOOD
var apiKey = builder.Configuration["OpenAI:ApiKey"]
?? throw new InvalidOperationException("OpenAI:ApiKey is not configured.");
```
## SQL 注入防范
* 始终使用 ADO.NET、Dapper 或 EF Core 的参数化查询
* 切勿将用户输入直接拼接到 SQL 字符串中
* 在使用动态查询构建时,先对排序字段和筛选操作符进行验证
```csharp
const string sql = "SELECT * FROM Orders WHERE CustomerId = @customerId";
await connection.QueryAsync<Order>(sql, new { customerId });
```
## 输入验证
* 在应用程序边界处验证 DTO
* 使用数据注解、FluentValidation 或显式的守卫子句
* 在执行业务逻辑之前拒绝无效的模型状态
## 身份验证与授权
* 优先使用框架提供的身份验证处理器,而非自定义的令牌解析逻辑
* 在端点或处理器边界强制执行授权策略
* 切勿记录原始令牌、密码或个人身份信息 (PII)
## 错误处理
* 返回面向客户端的、安全的错误信息
* 在服务器端记录包含结构化上下文的详细异常信息
* 切勿在 API 响应中暴露堆栈跟踪、SQL 语句或文件系统路径
## 参考资料
有关更广泛的应用安全审查清单,请参阅技能:`security-review`

View File

@@ -0,0 +1,47 @@
---
paths:
- "**/*.cs"
- "**/*.csx"
- "**/*.csproj"
---
# C# 测试
> 本文档扩展了 [common/testing.md](../common/testing.md) 中关于 C# 的特定内容。
## 测试框架
* 单元测试和集成测试首选 **xUnit**
* 使用 **FluentAssertions** 编写可读性强的断言
* 使用 **Moq****NSubstitute** 来模拟依赖项
* 当集成测试需要真实基础设施时,使用 **Testcontainers**
## 测试组织
*`tests/` 下镜像 `src/` 的结构
* 明确区分单元测试、集成测试和端到端测试的覆盖范围
* 根据行为而非实现细节来命名测试
```csharp
public sealed class OrderServiceTests
{
[Fact]
public async Task FindByIdAsync_ReturnsOrder_WhenOrderExists()
{
// Arrange
// Act
// Assert
}
}
```
## ASP.NET Core 集成测试
* 使用 `WebApplicationFactory<TEntryPoint>` 进行 API 集成测试覆盖
* 通过 HTTP 测试身份验证、验证和序列化,而不是绕过中间件
## 覆盖率
* 目标行覆盖率 80% 以上
* 将覆盖率重点放在领域逻辑、验证、身份验证和失败路径上
* 在 CI 中运行 `dotnet test` 并启用覆盖率收集(在可用的情况下)