Blazor基于数据库的本地化实现求助:替代.resx方案
Blazor 数据库本地化实现方案
适配Blazor的可用包
- Localization.SqlLocalizer:最新版本已适配Blazor,支持从SQL Server、MySQL等主流数据库读取本地化资源。配置时只需在
Program.cs中注册服务并指定数据库连接字符串即可快速集成。 - Blazor.Localization.Database:轻量级社区专用包,针对Blazor场景优化,提供资源增删改查API和简洁的本地化调用方式,适合小型项目快速落地。
自行实现IStringLocalizer步骤
如果没有合适的包满足需求,可以手动实现IStringLocalizer接口,以下是核心步骤:
1. 定义数据库实体与DbContext
首先创建存储本地化资源的实体类和EF Core上下文:
// 本地化资源实体 public class LocalizationResource { public int Id { get; set; } public string Key { get; set; } = string.Empty; public string Culture { get; set; } = string.Empty; public string Value { get; set; } = string.Empty; } // 数据库上下文 public class LocalizationDbContext : DbContext { public LocalizationDbContext(DbContextOptions<LocalizationDbContext> options) : base(options) { } public DbSet<LocalizationResource> LocalizationResources { get; set; } }
2. 实现IStringLocalizer接口
自定义本地化资源读取类,从数据库获取对应文化的资源:
public class DbStringLocalizer : IStringLocalizer { private readonly LocalizationDbContext _dbContext; private readonly string _cultureName; public DbStringLocalizer(LocalizationDbContext dbContext, string cultureName) { _dbContext = dbContext; _cultureName = cultureName; } public LocalizedString this[string name] { get { var value = _dbContext.LocalizationResources .FirstOrDefault(r => r.Key == name && r.Culture == _cultureName)? .Value; return new LocalizedString(name, value ?? name, resourceNotFound: value == null); } } public LocalizedString this[string name, params object[] arguments] { get { var value = _dbContext.LocalizationResources .FirstOrDefault(r => r.Key == name && r.Culture == _cultureName)? .Value; var formatted = string.Format(value ?? name, arguments); return new LocalizedString(name, formatted, resourceNotFound: value == null); } } public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures) { var query = _dbContext.LocalizationResources.Where(r => r.Culture == _cultureName); if (includeParentCultures) { var parentCulture = CultureInfo.GetCultureInfo(_cultureName).Parent.Name; query = query.Union(_dbContext.LocalizationResources.Where(r => r.Culture == parentCulture)); } return query.Select(r => new LocalizedString(r.Key, r.Value, false)); } public IStringLocalizer WithCulture(CultureInfo culture) { return new DbStringLocalizer(_dbContext, culture.Name); } }
3. 实现IStringLocalizerFactory
创建工厂类用于生成DbStringLocalizer实例:
public class DbStringLocalizerFactory : IStringLocalizerFactory { private readonly IServiceProvider _serviceProvider; public DbStringLocalizerFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IStringLocalizer Create(Type resourceSource) { var dbContext = _serviceProvider.GetRequiredService<LocalizationDbContext>(); var culture = CultureInfo.CurrentUICulture.Name; return new DbStringLocalizer(dbContext, culture); } public IStringLocalizer Create(string baseName, string location) { var dbContext = _serviceProvider.GetRequiredService<LocalizationDbContext>(); var culture = CultureInfo.CurrentUICulture.Name; return new DbStringLocalizer(dbContext, culture); } }
4. 注册服务并在组件中使用
在Program.cs中注册数据库上下文和本地化服务:
builder.Services.AddDbContext<LocalizationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("LocalizationDb"))); builder.Services.AddSingleton<IStringLocalizerFactory, DbStringLocalizerFactory>(); builder.Services.AddLocalization();
在Blazor组件中注入并使用:
@inject IStringLocalizer<Home> Localizer <h3>@Localizer["Greeting"]</h3> <p>@Localizer["WelcomeText", "Blazor"]</p>
优化建议
- 添加内存缓存:使用
IMemoryCache缓存已读取的本地化资源,减少数据库查询次数。 - 支持资源热更新:定期刷新缓存或监听数据库变化,实现无需重启应用即可更新本地化资源。
内容的提问来源于stack exchange,提问作者mitotomi
相关产品推荐
相关产品推荐

