You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Abp框架配置TextTemplate Provider从数据库而非虚拟文件系统读取模板

ABP框架配置Scriban从数据库读取模板的实现方案

完全可以通过自定义模板提供器实现该需求,无需依赖默认的虚拟文件系统读取.tpl文件,具体实现步骤如下:

1. 定义模板存储实体

首先创建用于存储Scriban模板的数据库实体,基础字段参考如下:

public class ScribanTemplate : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
    // 模板唯一名称,对应原虚拟文件路径作为查询Key,例如:/Templates/Email/Welcome.tpl
    public string Name { get; set; }
    // Scriban模板内容
    public string Content { get; set; }
    // 模板是否启用
    public bool IsEnabled { get; set; }
    // 多租户Id,不需要多租户可以删除
    public Guid? TenantId { get; set; }
}

将实体添加到项目的DbContext中,执行EF Core迁移生成对应数据库表。

2. 实现自定义模板内容提供器

ABP的Scriban模块通过ITemplateContentProvider接口获取模板内容,你只需实现该接口,替换默认的虚拟文件实现即可:

public class DatabaseTemplateContentProvider : ITemplateContentProvider, ITransientDependency
{
    private readonly IRepository<ScribanTemplate, Guid> _templateRepository;
    // 可选:注入默认虚拟文件提供器,实现数据库查不到时回退到文件系统
    private readonly VirtualFileTemplateContentProvider _virtualFileProvider;

    public DatabaseTemplateContentProvider(
        IRepository<ScribanTemplate, Guid> templateRepository,
        VirtualFileTemplateContentProvider virtualFileProvider)
    {
        _templateRepository = templateRepository;
        _virtualFileProvider = virtualFileProvider;
    }

    public async Task<string> GetContentAsync(string templateName, CancellationToken cancellationToken = default)
    {
        var template = await _templateRepository.FirstOrDefaultAsync(
            t => t.Name == templateName && t.IsEnabled,
            cancellationToken
        );

        if (template != null)
        {
            return template.Content;
        }

        // 可选:回退到虚拟文件系统查询,不需要可以删除直接抛异常
        return await _virtualFileProvider.GetContentAsync(templateName, cancellationToken);
    }
}

3. 替换默认服务

在模块类的ConfigureServices方法中,将自定义提供器注册为ITemplateContentProvider的默认实现:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    // 替换默认的模板内容提供器
    context.Services.Replace(
        ServiceDescriptor.Transient<ITemplateContentProvider, DatabaseTemplateContentProvider>()
    );

    // 其他服务配置...
}

优化建议

  • 可以给模板内容添加缓存,避免每次渲染模板都查询数据库,更新模板时同步清除对应缓存即可,性能和默认虚拟文件方案基本一致
  • 可以给模板实体扩展分类、描述、版本号等字段,实现模板的版本管理、分类检索能力

注意:如果不需要兼容原虚拟文件的模板,直接删除自定义提供器中回退到VirtualFileTemplateContentProvider的逻辑即可。

内容的提问来源于stack exchange,提问作者Darth Shirr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:54:05