基于EF Core存储的国际化服务
前言
.NET 官方有一个用来管理国际化资源的扩展包Microsoft.Extensions.Localization,ASP.NET Core也用这个来实现国际化功能。但是这个包的翻译数据是使用resx资源文件来管理的,这就意味着无法动态管理。虽然官方有在文档中提供了一些第三方管理方案,但是都不太方便。其中一个是基于Json文件的,虽然可以动态管理,但是正确的Key值有时很难猜对,特别是对于嵌套类和泛型类之类名字比较特殊的。另外两个基于EF Core的一个只是个demo;另一个已多年未更新,且上下文生命周期和并发管理有缺陷(这个库还是我提交pr才支持的 .NET 5)。最近项目有用到国际化功能,只好重新写一个。
新书宣传
有关新书的更多介绍欢迎查看《C#与.NET6 开发从入门到实践》上市,作者亲自来打广告了!

正文
这个扩展包代码不多也不算复杂,主要结构参考官方内置实现。对于 .NET 5以上支持上下文工厂的版本使用上下文工厂,而对于旧版本则创建内部作用域获取私有上下文,以此彻底避免并发问题。作用域和上下文都是需要查询时临时获取和使用,查询完数据立即销毁避免内存泄漏。如果使用池化上下文工厂性能会更好。
对代码感兴趣的朋友可以移步Github。这里直接介绍一下基本用法。
这个库分为三个包:抽象包定义了所需接口,实体模型包定义基本实体类型,功能包定义了服务接口的实现类和用于注册服务的扩展方法。方便为分离项目的解决方案按需引用,减少无关类型的污染。
以在ASP.NET Core中使用为例:
实体模型和上下文
public class YourLocalizationRecord : LocalizationRecord
{
public int YourProperty { get; set; }
}
public class YourDbContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 使用默认类型。
modelBuilder.UseLocalizationRecord();
// 使用自定义类型,需要继承LocalizationRecord。
modelBuilder.UseLocalizationRecord<YourLocalizationRecord>(b =>
{
b.Property(r => r.ResourceCulture).HasMaxLength(32);
b.ToTable($"{nameof(YourLocalizationRecord)}s");
});
}
}
服务注册
// 对于 .NET 5 以上请使用上下文工厂。
services.AddDbContextFactoty<YourDbContext>(options => options.UseSqlite("Localization.db"));
// 或者池化工厂也是一样的,而且更好。
services.AddPooledDbContextFactoty<YourDbContext>(options => options.UseSqlite("Localization.db"));
// 注册一个自定义工厂服务模拟作用域上下文服务
services.AddScoped<YourDbContext>(sp => sp.GetRequiredService<IDbContextFactory<YourDbContext>>().CreateDbContext());
// 对于 .NETStandard 2.0 或 2.1 请使用上下文。
services.AddDbContext<YourDbContext>(options => options.UseSqlite("Localization.db"));
// 注册使用默认实体类型的服务。
services.AddEntityFrameworkCoreLocalization<YourDbContext>(options =>
{
options.ResourcesPath = "Resources";
// 是否自动创建缺失的资源记录
options.CreateLocalizationResourcesIfNotExist = true;
});
// 注册使用自定义实体类型的服务。
services.AddEntityFrameworkCoreLocalization<YourDbContext, YourLocalizationRecord>(options =>
{
options.ResourcesPath = "Resources";
// 是否自动创建缺失的资源记录
options.CreateLocalizationResourcesIfNotExist = true;
});
其他的和官方文档用法完全一致,如果需要清除缓存使资源能在下次读取时更新,可以使用服务IDynamicResourceStringLocalizerFactory。这个服务继承自内置服务,获取的IStringLocalizerFactory服务实际上也是IDynamicResourceStringLocalizerFactory的实现。
既然已经有上下文了,想怎么读写数据应该不必多言了吧。实体类的属性LocalizedContent就是翻译后的文本。如果使用自动创建记录,只需要查找所有这个属性为null的记录并翻译保存,最后清除缓存即可。

结语
为了实现对 .NETStantard 2.0 的兼容代码上使用了条件编译预处理实现一份代码一个项目同时编译到所有框架,最大程度共用代码简化代码管理。
附上国际化官方文档:使 ASP.NET Core 应用内容可本地化,在本地化 ASP.NET Core 应用中为每个请求选择语言/区域性
许可证:MIT
代码仓库:CoreDX.Extensions.Localization.EntityFrameworkCore - Github
Nuget:CoreDX.Extensions.Localization.EntityFrameworkCore
Nuget:CoreDX.Extensions.Localization.EntityFrameworkCore.Abstractions
Nuget:CoreDX.Extensions.Localization.EntityFrameworkCore.Models
QQ群
读者交流QQ群:540719365

欢迎读者和广大朋友一起交流,如发现本书错误也欢迎通过博客园、QQ群等方式告知笔者。
本文地址:https://www.cnblogs.com/coredx/p/18294729.html
基于EF Core存储的国际化服务的更多相关文章
- C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
C# 嵌入dll 在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...
- 基于EF Core的Code First模式的DotNetCore快速开发框架
前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...
- 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持
前言 距离上一篇文章<基于EF Core的Code First模式的DotNetCore快速开发框架>已过去大半个年头,时光荏苒,岁月如梭...比较尴尬的是,在这大半个年头里,除了日常带娃 ...
- .net Core 基于EF Core 实现数据库上下文
在做项目时,需要将某一些功能的实体建立在另一个数据库中,连接不同的数据库用以存储记录.通过查找资料,实现EF Core上下文. 下面是实现上下文后的解决方案的目录: 1.UpAndDownDbCont ...
- 基于ef core 2.0的数据库增删改审计系统
1.首先是建审计存储表 CREATE TABLE [dbo].[Audit] ( [Id] [uniqueidentifier] NOT NULL, [EntityName] [nvarchar](1 ...
- 统一流控服务开源:基于.Net Core的流控服务
先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发,并在生产系统进行了大半年的验证,稳定可靠.今天整理一下 ...
- 使用Asp.Net Core MVC 开发项目实践[第四篇:基于EF Core的扩展2]
上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据. 先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行 第一种更新扩展: 自定义更新字 ...
- 使用Asp.Net Core MVC 开发项目实践[第三篇:基于EF Core的扩展]
上篇我们说到了EFCore的基础使用,这篇我们将讲解下基于EFCore的扩展. 我们在Mango.Framework.EFCore类库项目中创建一个类名EFExtended的扩展类,并且引入相关的命名 ...
- Net Core的流控服务
统一流控服务开源:基于.Net Core的流控服务 先前有一篇博文,梳理了流控服务的场景.业界做法和常用算法 统一流控服务开源-1:场景&业界做法&算法篇 最近完成了流控服务的开发 ...
- .Net Core Grpc Consul 实现服务注册 服务发现 负载均衡
本文是基于..net core grpc consul 实现服务注册 服务发现 负载均衡(二)的,很多内容是直接复制过来的,..net core grpc consul 实现服务注册 服务发现 负载均 ...
随机推荐
- IPv6 — 网际协议第 6 版
目录 文章目录 目录 IPv6 IPv6 的发展 IPv6 网络基本概念 IPv6 的特性 IPv4 与 IPv6 的比较 IPv6 IPv6(Internet Protocol version 6, ...
- java学习之旅(day.15)
IO框架 I:input O:output 流:内存与存储设备间传输数据的通道 数据借助流进行传输 流的分类 按流向分: 输入流:将存储设备中的内容读入到内存中(程序运行) 输出流:将内存中的内容写入 ...
- Clip-跳过
在 Stable Diffusion 1.x 模型中,CLIP 用作文本嵌入.CLIP模型由多层组成.他们一层一层地变得更加具体.过于简单化,第一层可以理解"人",第二层可以区分& ...
- Android 13 - Media框架(28)- MediaCodec(三)
关注公众号免费阅读全文,进入音视频开发技术分享群! 上一节我们了解到 ACodec 执行完 start 流程后,会把所有的 input buffer 都提交给 MediaCodec 层,MediaCo ...
- C# wpf之控制屏幕显示方向旋转
using System;using System.Collections.Generic;using System.Linq;using System.Runtime.InteropServices ...
- 怎么使用Stable diffusion中的models
Stable diffusion中的models Stable diffusion model也可以叫做checkpoint model,是预先训练好的Stable diffusion权重,用于生成特 ...
- itest(爱测试) 4.5.7 发布,开源BUG 跟踪管理 & 敏捷测试管理&极简项目管理软件
itest 简介 itest 开源敏捷测试管理,testOps 践行者,极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试5合1,又有丰富的统计分析.可按测试包分配测试用例执行,也可建测试迭代 ...
- ARM汇编基础
1 GNU语法 1.1 GNU汇编 GNU 汇编语法适用于所有的架构,并不是 ARM 独享的,GNU 汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分,如下: label: instruc ...
- react移动端组件antd-mobile
使用react移动端组件antd-mobile完成底部导航功能实现. 官网:https://mobile.ant.design/docs/react/introduce-cn antd-mobile ...
- Vulkan Support Check and Dynamic Loader C++ code sample
很多时候不想静态依赖VulkanSDK所提供的静态库,因为会遇到一些过早的电脑不支持vulkan, 那么就需要使用动态加载vulkan-1.dll(for Windows)或libMoltenVK.d ...