一个拒绝过度设计的 .NET 快速开发框架:开箱即用,专注"干活"
在 .NET 生态中,我们见过太多“高大上”的框架:依赖注入、AOP、微服务、事件溯源……这些设计模式固然强大,但对于大多数中小型项目或快速原型开发来说,它们往往成为“屠龙之技”——过度设计导致学习成本高、启动慢、改不动。今天,我要介绍的是一个反其道而行之的框架:轻量、务实、开箱即用。它不追求“全宇宙最强架构”,只追求“今天写代码,明天上线”。## 为什么需要拒绝过度设计?很多团队陷入一个误区:“先用最复杂的设计,未来好扩展”。结果呢?项目还没上线,团队先被复杂配置、多层抽象、性能损耗拖垮。过度设计带来的问题包括:-学习曲线陡峭:新成员加入后,需要花一周理解“服务定位器”和“装饰器模式”的嵌套。-调试困难:一个简单的 CRUD 操作,经过 5 层接口抽象、3 个代理类,出 bug 时难以定位。-性能浪费:每个请求都经过“中间件管道、过滤器链、事件总线”,实际业务逻辑只占 10% 时间。这个框架的核心哲学是:“能简单,绝不复杂”。它采用扁平化结构,直接操作数据库,无需定义复杂的仓储接口,无需配置 IoC 容器。下面通过代码感受一下。## 快速开始:一个完整的 CRUD 示例假设我们要做一个“任务管理”系统,包含增删改查。传统做法需要定义ITaskRepository、TaskService、TaskController以及一堆 DTO。而在这个框架中,你只需要一个类。### 安装与配置首先,通过 NuGet 安装框架包(假设包名为FastCrud.Core):bashdotnet add package FastCrud.Core然后在Program.cs中一行代码完成初始化:csharp// Program.csusing FastCrud.Core;var builder = WebApplication.CreateBuilder(args);builder.Services.AddFastCrud(); // 注册核心服务,自动扫描实体和控制器var app = builder.Build();app.UseFastCrud(); // 启用自动路由和 CRUD 端点app.Run();### 定义实体模型无需配置 Fluent API 或数据注释,框架按约定自动映射:csharp// Models/TaskItem.csusing FastCrud.Core.Attributes;[TableName("Tasks")] // 指定数据库表名,默认使用类名public class TaskItem{ [PrimaryKey, AutoIncrement] // 主键自增 public int Id { get; set; } [Required(ErrorMessage = "标题不能为空")] public string Title { get; set; } public string? Description { get; set; } [DefaultValue("pending")] // 默认值 public string Status { get; set; } = "pending"; public DateTime CreatedAt { get; set; } = DateTime.UtcNow;}### 自动生成 API 端点框架扫描所有继承BaseEntity的类,自动生成 RESTful API。无需写 Controller。启动项目后,以下端点自动生效:-GET /api/TaskItem– 获取列表(支持分页、排序、过滤)-GET /api/TaskItem/{id}– 获取单个-POST /api/TaskItem– 新增-PUT /api/TaskItem/{id}– 更新-DELETE /api/TaskItem/{id}– 删除无代码,零配置。你甚至不需要写一行 Controller 代码。## 进阶使用:自定义业务逻辑框架允许你“嵌入”自定义逻辑,而无需抛弃自动 CRUD。比如,我们想给新增任务时自动发送通知:csharp// Services/TaskService.csusing FastCrud.Core.Services;public class TaskService : ICrudService<TaskItem>{ private readonly ICrudRepository<TaskItem> _repository; private readonly INotificationService _notification; // 框架自动注入依赖(无需手动注册) public TaskService(ICrudRepository<TaskItem> repository, INotificationService notification) { _repository = repository; _notification = notification; } // 重写新增方法,保留自动映射+添加额外逻辑 public async Task<TaskItem> CreateAsync(TaskItem task) { // 自动验证、写入数据库 var createdTask = await _repository.CreateAsync(task); // 发送通知 await _notification.SendAsync($"新任务:{createdTask.Title}"); return createdTask; } // 其他方法(GetAll、GetById、Update、Delete)默认使用基类的自动实现}然后在Program.cs中注册自定义服务:csharpbuilder.Services.AddScoped<ICrudService<TaskItem>, TaskService>();框架会自动替换默认的 CRUD 处理,其他实体(如User、Project)仍然使用自动实现。这种“选择性覆盖”设计,既保留了开箱即用的效率,又提供了灵活扩展的入口。## 性能与数据访问框架底层使用原生的ADO.NET+Dapper,没有复杂的 ORM 开销。以下是一个手动查询示例(当自动 CRUD 不满足时):csharp// Repositories/CustomTaskRepository.cspublic class CustomTaskRepository : ICrudRepository<TaskItem>{ private readonly IDbConnection _db; // 框架自动注入数据库连接 public async Task<IEnumerable<TaskItem>> GetOverdueTasks() { // 直接写 SQL,无需 LINQ 或表达式树 var sql = @" SELECT * FROM Tasks WHERE Status = 'pending' AND CreatedAt < @threshold ORDER BY CreatedAt DESC"; return await _db.QueryAsync<TaskItem>(sql, new { threshold = DateTime.UtcNow.AddHours(-24) }); }}这种“直接 SQL”的方式,对于复杂查询(如多表 JOIN、聚合函数)反而更高效。框架不限制你使用 ORM 方式,但推荐:80% 的简单操作用自动 CRUD,20% 的复杂操作写原生 SQL。## 总结这个快速开发框架的设计理念,可以用一句话概括:“框架是辅助,不是主角”。它不强迫你接受某种“最佳实践”,而是提供一个“最小可行工具集”。当你需要快速搭建一个后台管理系统、内部工具或 API 网关时,它让你专注于业务逻辑,而不是框架配置。核心优势:- 零配置启动:一个 NuGet 包,两行代码,CRUD 端点到手。- 可选择性覆盖:自定义逻辑时,不需要重构整个架构。- 性能透明:底层使用轻量级数据访问,没有隐藏的“黑魔法”。如果你厌倦了“为了用框架而用框架”的过度设计,不妨试试这种“返璞归真”的方式。记住:代码的最终目标是解决问题,而不是展示设计模式。