《从AI生成到配置驱动(三)—— 这套能跨语言、不依赖ORM的全栈轻量级架构,长什么样?》
作者:咏方舟-长江之流
日期:2026-07-11
前言:从“前端配置”到“全栈基架”
前两篇文章,我们从一个 AI 生成的 productdemo.html 出发,先展示了它“能用”的一面,又剖析了它“难维护”的一面。最终我抛出了一个观点:与其让 AI 不断生成雷同的 CRUD 代码,不如把 业务配置 和 UI 渲染 彻底分离,让前端通过 XML 配置即可驱动完整页面。
但“配置驱动”这件事,光有前端框架是不够的 —— 后端如果不够轻量、不够规范、不够跨平台,前端的配置就变成了空中楼阁。
所以这一篇,我把视角从前端拉回到全栈,完整梳理支撑这套理念的底层架构。
目前我正在推进的一项核心工作,是将此前基于 XML 配置的报表与 CRUD 功能模块,整体迁移至 Visual Studio 2026 开发平台,并对底层架构进行深度优化重构。
这次重构的关键,在于选用 .NET Standard 作为底层基础库的规范标准。.NET Standard 是跨所有 .NET 实现的统一接口规范(相当于一份“API 契约”),基于它编写的类库,可以被两类运行时同时调用:一类是 Windows 专属的经典运行时 .NET Framework,另一类是跨平台的新一代运行时实现 .NET Core(现已统称为 .NET 5+)。
通过这一架构设计,我希望在兼容现有 Windows 生态的同时,也为未来的跨平台部署留出充分空间,让“配置驱动”的前端方案能够真正跑通全栈、适配多端。
基于这一目标,我将三个项目(Foundation / Core / WebAPI)所应用的技术架构,从分层逻辑、设计模式、技术选型、跨语言约束四个维度重新梳理如下:

全开方式的轻量级架构,同样的XML配置,前后端无需一行代码,但是你可以自己写前端提供者,切换风格

一、总体定位:轻量级企业级分层架构
- 目标:在不用 EF、不用 Dapper 的前提下,构建一套 可跨语言迁移(C# → ArkTS)、数据库方言可适配、业务逻辑纯净可测试 的轻量级基架。
- 哲学:SQL 是唯一真正的跨平台标准;Foundation 是只读基架,业务层做适配,不越界修改底层。
二、三个项目的分层边界
| 项目 | 定位 | 依赖关系 | 包含内容 |
|---|---|---|---|
UserBaoTech.Foundation | 公司级技术基架(只读) | 零第三方依赖(仅 .NET Standard 2.0 + System.Text.Json) | 接口(IEntity/IRepository/IService)、基类(RepositoryBase/ServiceBase/KeyServiceBase)、基础设施抽象(ILogger/ICacheProvider/IConfigProvider)、方言执行器(DataAccessExecutor)、统一返回(MessageResult) |
GushiChaodi.Core | 业务领域层(可写) | 引用 Foundation | 业务实体(Product)、查询模型(ProductQuery)、DTO(CreateProductRequest/UpdateProductRequest)、仓储实现(ProductRepository)、业务服务(GetProductListService / CreateProductService / KeyService 派生类) |
GushiChaodi.WebAPI | 接入层(可写) | 引用 Foundation + Core | Controller(ProductController)、启动配置(Program.cs 注册 DI/CORS/StaticFiles)、配置文件(appsettings.json)、前端静态页(productdemo.html) |
三、分层逻辑(自顶向下)
┌─────────────────────────────────────────────────────┐
│ 表现层(WebAPI) │
│ - Controller 接收 HTTP 请求,参数自动绑定 │
│ - 依赖注入 Service,不直接 new │
│ - 返回 MessageResult<T> 统一格式 │
└─────────────────────────────────────────────────────┘
│ 调用
▼
┌─────────────────────────────────────────────────────┐
│ 业务服务层(Core.Services) │
│ - 继承 ServiceBase<TParam, TResult> │
│ - 单参数主键场景继承 KeyServiceBase<TResult> │
│ - 负责业务校验、事务控制、调用仓储 │
│ - 纯 C# 逻辑,无 .NET 特有类型(可迁移 ArkTS) │
└─────────────────────────────────────────────────────┘
│ 依赖接口
▼
┌─────────────────────────────────────────────────────┐
│ 仓储接口层(Foundation.Data.IRepository<T>) │
│ - 定义 CRUD 契约(Query/GetById/Insert/Update/Delete)│
│ - 单泛型默认 string 主键,双泛型支持任意主键类型 │
└─────────────────────────────────────────────────────┘
│ 实现
▼
┌─────────────────────────────────────────────────────┐
│ 仓储实现层(Core.Data.ProductRepository) │
│ - 继承 RepositoryBase<Product> │
│ - 必须实现:表名、MapToEntity、GetInsertValues、GetUpdateValues│
│ - 可重写:Delete(软删除)、GenerateId、NeedGetIdentityAfterInsert│
└─────────────────────────────────────────────────────┘
│ 内部使用
▼
┌─────────────────────────────────────────────────────┐
│ 轻量数据执行器(Foundation.DataAccessExecutor) │
│ - 封装 ADO.NET(IDbConnection/IDbCommand/IDataReader)│
│ - 统一处理方言:参数前缀(@/:)、分页 SQL、自增 ID 回读、日期格式│
│ - 上层(Repository)完全感知不到数据库差异 │
└─────────────────────────────────────────────────────┘
│ 连接
▼
┌─────────────────────────────────────────────────────┐
│ 物理数据库(MySQL / SQL Server / Oracle / SQLite)│
└─────────────────────────────────────────────────────┘
四、核心设计模式
| 模式 | 应用位置 | 作用 |
|---|---|---|
| 仓储模式(Repository) | IRepository<T> + RepositoryBase<T> | 隔离数据访问,业务层只依赖接口 |
| 工作单元(UnitOfWork) | IUnitOfWork + UnitOfWork | 管理事务边界,多仓储共享同一事务 |
| 模板方法模式 | ServiceBase / KeyServiceBase | 基类处理日志/缓存/异常,子类只写 DoExecuteAsync |
| 依赖注入(DI) | Program.cs + ServiceRegistrar | 替代静态工厂,统一生命周期管理(Scoped/Transient/Singleton) |
| 工厂模式(方言适配) | DataAccessExecutor 内部 switch | 根据 DatabaseType 生成不同数据库方言 SQL |
五、技术选型清单
| 层次 | 技术 | 版本/说明 |
|---|---|---|
| 基架目标框架 | .NET Standard 2.0 | 兼容所有 .NET 运行时,永不淘汰 |
| 业务层/接入层 | .NET 10(VS2026 默认) | WebAPI / WinForms 均可 |
| 语言版本 | C# 7.3 | 禁用 C# 8.0+ 语法(如 using var),确保兼容性 |
| 数据库驱动 | MySqlConnector | 也可替换为 System.Data.SqlClient / Npgsql 等 |
| JSON 序列化 | System.Text.Json | 官方高性能库,通过 NuGet 引用 |
| 日志/缓存/配置 | 接口抽象 + Null 默认实现 | 可插拔,不绑定具体实现 |
| 前端调试页 | 原生 HTML + JavaScript | 零框架依赖,直接放 wwwroot |
| 依赖注入 | Microsoft.Extensions.DependencyInjection | 官方 DI 容器 |
| 自动注册工具 | ServiceRegistrar(外围工具) | 按命名规范(Repository/Service 后缀)自动扫描注册 |
六、不可更改的设计准则(ADR 核心)
- Foundation 层绝对不动:视为只读三方依赖,即使有 bug 也在 Core/WebAPI 层适配解决。
- 手写 SQL + 参数化查询:不用 EF,不用 Dapper,SQL 语句跨端(C#/ArkTS)完全一致。
- 主键优先用 string(GUID 程序生成):特殊场景(自增 INT)通过
NeedGetIdentityAfterInsert = true切换。 - 软删除默认过滤:列表查询默认
IsDeleted = false,由业务层 Service 控制默认值。 - 分页索引统一规则:前端传
1开始,在 Core 层 Service 中统一转换为0开始再传给DataAccessExecutor。 - 单参数主键操作一律用
KeyRequest:不定义GetXxxByIdRequest/DeleteXxxRequest等冗余 DTO。 - 统一返回格式:分页用
rows + total,非分页用data,不混用。
七、跨语言迁移(C# → 鸿蒙 ArkTS)镜像关系
| C# | ArkTS |
|---|---|
IEntity<TKey> | IBaseModel |
IRepository<T> | IBaseDao<T> |
RepositoryBase<T> | BaseDao<T> |
IService<TParam,TResult> | IBaseService<TParam,TResult> |
ServiceBase<TParam,TResult> | BaseService<TParam,TResult> |
KeyServiceBase<TResult> | KeyBaseService<TResult> |
MessageResult<T> | MessageResult<T>(JSON 结构一致) |
| 手写 SQL | 手写 SQL(鸿蒙 relationalStore 执行) |
结语
以上就是三个项目的完整技术架构定义。这套架构的核心思想可以概括为一句话:
用最轻的方式,把数据访问层抽象到极致,让上层业务既感知不到数据库差异,也感知不到运行环境差异。
后续所有新模块开发、Bug 修复、扩展设计,都将严格遵循这套准则。而在这套基架之上,前端 XML 配置驱动也好,AI 生成代码也好,都有了稳固的落脚点——不会因为换了数据库、换了前端框架、甚至换了编程语言,就需要把整个底层推倒重来。
架构的价值,从来不在当下,而在未来。
本文首发于 CSDN,作者:咏方舟-长江之流,无需授权,欢迎转载。
如果你觉得有用,欢迎点赞、收藏、评论。
回顾上一篇:[《AI 写的前端代码,为什么总是“能用但难维护”?—— 一个 productdemo.html 的架构评审实录(二)》](#)
—— 这套能跨语言、不依赖ORM的全栈轻量级架构,长什么样?&spm=1001.2101.3001.5002&articleId=162790466&d=1&t=3&u=55d218875e7347ed89cc292c63f36cd1)

被折叠的 条评论
为什么被折叠?



