Skip to content

开发规范

本文档定义 youlai-aspnet 后端项目的开发约定,参考微软官方编码规范及业界最佳实践。

命名规范

命名空间命名

规则示例说明
PascalCaseYoulai.Application.Services✅ 正确
单词间无分隔Youlai.ApplicationService❌ 错误

命名空间结构

Youlai
├── Api/                    # Web API 层
│   ├── Controllers/        # 控制器
│   ├── Middleware/         # 中间件
│   └── Security/           # 安全配置
├── Application/            # 应用层
│   ├── Common/             # 公共组件
│   ├── System/             # 系统模块
│   └── Auth/               # 认证模块
├── Domain/                 # 领域层
│   └── Entities/           # 实体类
└── Infrastructure/         # 基础设施层
    ├── Persistence/        # 持久化
    └── Services/           # 基础服务

类命名

类型规则示例
控制器XxxControllerUsersController
服务接口IXxxServiceIUserService
服务实现XxxServiceUserService
实体类XxxSysUser
DTOXxxDtoUserPageDto
表单对象XxxFormUserForm
查询对象XxxQueryUserQuery
枚举类XxxDataScope
常量类XxxConstantsSecurityConstants
配置类XxxOptionsJwtOptions
异常类XxxExceptionBusinessException

方法命名

查询方法

方法前缀说明示例
Get单个对象查询GetUserByIdAsync()GetUserFormAsync()
List列表查询ListUsersAsync()ListUserOptionsAsync()
GetPage分页查询GetUserPageAsync()
Exists存在性判断ExistsByUsernameAsync()
csharp
// ✅ 推荐
Task<User?> GetUserByIdAsync(long id);
Task<List<User>> ListUsersAsync(UserQuery query);
Task<PageResult<UserPageDto>> GetUserPageAsync(UserQuery query);
Task<bool> ExistsByUsernameAsync(string username);

// ❌ 不推荐
Task<User> SelectUser(long id);      // 应使用 Get
Task<List<User>> QueryUsers();       // 应使用 List

写操作方法

方法前缀说明示例
Save / Create新增SaveUserAsync()
Update修改UpdateUserAsync()
Delete删除DeleteUserAsync()
csharp
// ✅ 推荐
Task<bool> SaveUserAsync(UserForm form);
Task<bool> UpdateUserAsync(long id, UserForm form);
Task<bool> DeleteUsersAsync(string ids);

// ❌ 不推荐
Task<bool> AddUser();        // 应使用 Save/Create
Task<bool> ModifyUser();     // 应使用 Update
Task<bool> RemoveUser();     // 应使用 Delete

变量命名

类型规则示例
成员变量_camelCaseprivate readonly IUserService _userService;
局部变量camelCasevar user = await _userService.GetByIdAsync(id);
常量PascalCasepublic const string DefaultPassword = "123456";
布尔变量Is/Has/Can 前缀public bool IsRoot { get; set; }

分层架构规约

调用链路

各层职责

层级职责禁止事项
Api参数校验、调用 Service、组装返回结果❌ 禁止直接访问 DbContext
Application业务逻辑、事务控制、数据组装❌ 禁止跨业务调用 Repository
Infrastructure数据库访问、外部服务集成❌ 禁止包含业务逻辑

Service 调用规范

核心原则:Service 只能调用自己业务域的 Repository,禁止跨业务调用。

csharp
// ✅ 正确:UserService 调用 IUserRepository
public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;        // 自己业务域
    private readonly IUserRoleService _userRoleService;      // 通过 Service 交互

    public async Task<User?> GetUserByIdAsync(long id)
    {
        return await _userRepository.FindByIdAsync(id);
    }
}

// ❌ 错误:UserService 直接调用 IRoleRepository
public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;  // ❌ 禁止跨业务调用

    public async Task<User?> GetUserWithRolesAsync(long id)
    {
        var user = await _userRepository.FindByIdAsync(id);
        var roles = await _roleRepository.ListByUserIdAsync(id);  // ❌ 错误
        return user;
    }
}

// ✅ 正确:通过 IRoleService 获取角色
public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;
    private readonly IRoleService _roleService;  // ✅ 通过 Service 交互

    public async Task<User?> GetUserWithRolesAsync(long id)
    {
        var user = await _userRepository.FindByIdAsync(id);
        var roles = await _roleService.ListRolesByUserIdAsync(id);  // ✅ 正确
        return user;
    }
}

RESTful API 规范

URL 设计

规则示例说明
使用名词复数/api/v1/users✅ 正确
避免动词/api/v1/getUsers❌ 错误
层级不超过 3 层/api/v1/users/{id}/roles✅ 正确

HTTP 方法映射

HTTP 方法操作URL 示例
GET列表查询GET /api/v1/users
GET单个查询GET /api/v1/users/{id}
POST新增POST /api/v1/users
PUT全量修改PUT /api/v1/users/{id}
PATCH部分修改PATCH /api/v1/users/{id}/status
DELETE删除DELETE /api/v1/users/{id}

错误码规范

常用错误码

错误码说明场景
00000成功正常执行
A0001用户端错误一级宏观
A0200用户登录异常登录失败
A0230Token 无效或过期认证失败
A0301访问未授权权限不足
A0400请求参数错误参数校验失败
B0001系统执行出错一级宏观

日志规范

日志级别

级别场景
Error错误信息,需要立即处理
Warning警告信息,可能存在问题
Information关键流程信息
Debug调试信息

日志格式

csharp
// ✅ 推荐:使用结构化日志
_logger.LogInformation("用户登录成功:UserId={UserId}, Username={Username}", userId, username);
_logger.LogError(e, "用户登录失败:Username={Username}", username);

// ❌ 不推荐:字符串拼接
_logger.LogInformation($"用户登录成功:UserId={userId}");

最佳实践

避免魔法值

csharp
// ❌ 不推荐
if (user.Status == 1) { }

// ✅ 推荐:使用枚举
if (user.Status == UserStatus.Enabled) { }

// ✅ 推荐:使用常量
public static class UserStatus
{
    public const int Enabled = 1;
    public const int Disabled = 0;
}

集合判空

csharp
// ❌ 不推荐
if (list.Count > 0) { }

// ✅ 推荐
if (list.Count > 0) { }
// 或使用扩展方法
if (list.Any()) { }

字符串判空

csharp
// ❌ 不推荐
if (str != null && str.Length > 0) { }

// ✅ 推荐
if (!string.IsNullOrEmpty(str)) { }
// 或更严格(排除空白字符)
if (!string.IsNullOrWhiteSpace(str)) { }

避免 NullReferenceException

csharp
// ❌ 不推荐
return user.Username.Equals("admin");

// ✅ 推荐
return user.Username?.Equals("admin") == true;

// ✅ 推荐:使用模式匹配
return user.Username is "admin";

相关文件

文件说明
Youlai.Application/Common/Results/ResultCode.cs错误码枚举定义
Youlai.Api/Middleware/ExceptionMiddleware.cs全局异常处理
Youlai.Application/Common/Models/PageResult.cs分页结果基类

基于 MIT 许可发布