HuanMengAdmin/admin-server/MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode
2025-11-08 02:39:31 +08:00
..
Abstractions 2·1 2025-11-08 02:39:31 +08:00
Core 2·1 2025-11-08 02:39:31 +08:00
Impl 2·1 2025-11-08 02:39:31 +08:00
Providers 2·1 2025-11-08 02:39:31 +08:00
ICodeGenerationService.cs 2·1 2025-11-08 02:39:31 +08:00
README.md 3213 2025-11-08 00:02:14 +08:00

低代码平台数据源抽象架构说明

概述

低代码平台已重构为基于数据源提供者Provider模式的可扩展架构支持多数据源、配置驱动的代码生成。

核心架构

1. 抽象层 (Abstractions)

IDataSourceProvider

数据源提供者接口,定义了所有数据源必须实现的功能:

  • Config: 数据源配置信息
  • GetTables(): 获取数据库表信息
  • GetDbContext(): 获取数据库上下文

DataSourceConfig

数据源配置模型,包含:

  • DatabaseKey: 数据库标识Admin, MiaoYuChat, LiveForum
  • 路径模板: 支持占位符的路径配置
    • {RootPath}: 项目根路径
    • {AppPath}: 应用路径
    • {Namespace}: 实体命名空间
    • {EntityName}: 实体名称
    • {EntityNamePlural}: 实体名称复数形式
    • {TableName}: 表名
  • TemplatePath: 代码生成模板目录
  • NamingStrategy: 实体命名策略(保持原名/驼峰转换)

EntityNamingStrategy

命名策略枚举:

  • KeepOriginal: 保持数据库表名原样
  • ToPascalCase: 转换为驼峰命名(去除下划线前缀)

2. 核心工具 (Core)

DataSourceManager

数据源管理器,负责:

  • 自动收集所有注册的 IDataSourceProvider
  • 根据DatabaseKey获取对应的Provider
  • 聚合所有数据源的表信息

PathResolver

路径解析器,负责:

  • 解析路径模板中的占位符
  • 应用命名策略转换
  • 生成最终的文件路径

DataSourceExtensions

扩展方法集,提供:

  • ExtractDatabaseKey(): 从Schema中提取数据库标识
  • CleanSchema(): 清理Schema中的数据库标识

3. 数据源实现 (Providers)

AdminDataSourceProvider

后台管理系统数据源:

  • DatabaseKey: Admin
  • NamingStrategy: ToPascalCase(驼峰转换)
  • 模板路径: /wwwroot/code_generation/template/
  • 实体目录: 按复数形式分类(如 Entities\\Apps\\Users

MiaoYuChatDataSourceProvider

喵语AI聊天数据源

  • DatabaseKey: MiaoYuChat
  • NamingStrategy: KeepOriginal(保持原名)
  • 模板路径: /wwwroot/code_generation/templatev4/
  • 实体目录: 扁平结构(如 Entities\\Apps

新增数据源步骤

1. 创建Provider实现

Providers 目录下创建新的Provider类

public class NewDataSourceProvider : IDataSourceProvider, IScopedDependency
{
    private readonly IRepository<YourEntity> _repository;

    public NewDataSourceProvider(IRepository<YourEntity> repository)
    {
        _repository = repository;
    }

    public DataSourceConfig Config => new DataSourceConfig
    {
        DatabaseKey = DataSourceConstants.YourDatabase,
        DisplayName = "数据库显示名称",
        EntityNamespace = typeof(YourRepositoryStartup).Namespace!,
        ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\YourPath",
        ServicePathTemplate = "{AppPath}\\ApplicationServices\\YourPath",
        ControllerPathTemplate = "{AppPath}\\Controllers\\YourPath",
        ClientIndexPathTemplate = "{RootPath}\\admin-client\\src\\views\\YourPath",
        ClientInfoPathTemplate = "{RootPath}\\admin-client\\src\\views\\YourPath",
        ClientServicePathTemplate = "{RootPath}\\admin-client\\src\\services\\YourPath",
        TemplatePath = "/wwwroot/code_generation/template/",
        NamingStrategy = EntityNamingStrategy.ToPascalCase,
        Order = 3
    };

    public List<DbTableInfo> GetTables()
    {
        var tables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
        // 标记数据源来源
        tables.ForEach(t => t.Schema = t.Schema + "." + Config.DatabaseKey);
        return tables;
    }

    public DbContext GetDbContext() => _repository.GetContext()!;
}

2. 添加常量定义

DataSourceConstants 中添加新的数据库标识:

public const string YourDatabase = "YourDatabase";

3. 自动注册

由于Provider类实现了 IScopedDependency,依赖注入系统会自动注册。 DataSourceManager 会在构造函数中自动收集所有Provider实例。

4. 验证

启动项目后:

  1. 表同步功能会自动识别新数据源
  2. 代码生成会根据新配置生成相应代码
  3. 无需修改任何业务逻辑代码

关键服务说明

DatabaseTableService

  • GetAllTableInfos(): 获取所有数据源的表信息通过DataSourceManager聚合

CodeGenerationService

  • FillPathByLowCodeTable(): 根据数据源配置填充路径
  • GenModelAsync(): 根据数据源模板生成Model代码
  • GenServiceAsync(): 生成Service代码
  • GenControllerAsync(): 生成Controller代码
  • GenIndexAsync(): 生成前端Index页面
  • GenInfoAsync(): 生成前端Info页面
  • GenServiceJsAsync(): 生成前端Service代码

LowCodeTableService

  • SynchronizationAsync(): 同步所有数据源的表到低代码系统
    • 自动识别数据源
    • 应用相应的命名策略
    • 保存数据库标识和Schema信息

优势

  1. 开放封闭原则: 新增数据源无需修改现有代码只需添加Provider
  2. 配置驱动: 所有路径和行为都通过配置控制
  3. 类型安全: 使用强类型配置,编译时验证
  4. 可维护性: 每个数据源的逻辑独立,互不影响
  5. 可测试性: Provider可独立测试易于Mock

注意事项

  1. Provider必须实现 IScopedDependency 才能被自动注册
  2. GetTables() 中需要标记Schema以区分数据源t.Schema += "." + DatabaseKey
  3. 路径模板中的占位符大小写敏感
  4. Order属性控制数据源的显示顺序数字越小越靠前
  5. NamingStrategy影响实体类的命名需根据数据库命名规范选择

扩展性考虑

当前架构支持以下扩展:

  • 新的命名策略需扩展EntityNamingStrategy枚举
  • 自定义路径占位符需扩展PathResolver
  • 不同的模板引擎(需修改代码生成服务)
  • 多租户数据源需在Provider中实现动态配置