ABP vNext 提供了全套的本地化字符串支持,具体用法可以参考官方使用文档。vNext 本身是对 Microsoft 提供的本地化组件进行了实现,通过 JSON 文件提供本地化源,这一点与老 ABP 不太一样,老 ABP 框架是全套自己手撸。vNext 针对服务端和客户端都提供了文字本地化的工具类,这样开发人员可以很快速地开发支持多语言的网站程序。
二、源码分析本地化涉及的主要模块有 Volo.Abp.Localization.Abstractions 和 Volo.Abp.Localization,可以看到 Volo 针对包的结构也逐渐向 Microsoft 的构建方式靠拢。有直接依赖的模块是 Volo.Abp.VirtualFileSystem,之所以会引用到这个模块,是因为默认的本地化数据源是通过内嵌 JSON 文件实现的,所以会用到虚拟文件系统读取数据。
2.1 本地化的抽象接口首先打开 Volo.Abp.Localization.Abstractions 项目,它的基本结构如下图所示,需要注意的核心类型就是 ILocalizableString 接口和它的两个具体实现 FixedLocalizableString 与 LocalizableString。
这里的 IAbpStringLocalizerFactoryWithDefaultResourceSupport 接口是为 AbpStringLocalizerFactoryExtensions 服务的,后面会详细解释,主要作用是根据默认资源类型快速创建一个 IStringLocalizer 实例。
2.1.1 本地化字符串对象的封装可以看到在该项目内部定义了一个 ILocalizableString 的接口,在 ABP vNext 内部需要用到多语言表示的字符串属性,都是定义的 ILocalizableString 类型。本质上它是针对 Microsoft 提供的 LocalizedString 进行了一层包装,这个接口只提供了一个方法 Localize(),具体的签名见下面的代码。
public interface ILocalizableString { LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory); }在 ABP vNext 框架当中,拥有两个实现,分别是 LocalizableString 和 FixedLocalizableString,后者用于创建固定字串的显示。例如 ABP vNext 自带的权限系统,针对权限名称和描述必须传递 ILocalizableString 类型的值,但是开发人员暂时没有提供对应的本地化翻译,这个时候就可以使用 FixedLocalizableString 传递固定字符串。
实现也是很简单,在调用了 Localize() 方法之后,会根据构造函数的 Value 创建一个新的 LocalizedString 对象。
public class FixedLocalizableString : ILocalizableString { public string Value { get; } public FixedLocalizableString(string value) { Value = value; } public LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory) { return new LocalizedString(Value, Value); } }用法举例:
public class DataDictionaryDefinitionPermissionProvider : PermissionDefinitionProvider { public override void Define(IPermissionDefinitionContext context) { var dataDictionaryGroup = context.AddGroup(DataDictionaryPermissions.GroupName, L("Permission:DataDictionary")); var dataDictionary = dataDictionaryGroup.AddPermission(DataDictionaryPermissions.DataDictionary.Default, L("Permission:DataDictionary")); dataDictionary.AddChild(DataDictionaryPermissions.DataDictionary.Create, L("Permission:Create")); dataDictionary.AddChild(DataDictionaryPermissions.DataDictionary.Update, L("Permission:Edit")); dataDictionary.AddChild(DataDictionaryPermissions.DataDictionary.Delete, L("Permission:Delete")); // 这里使用了 FixedLocalizableString 提供本地化字符串。 dataDictionary.AddChild(DataDictionaryPermissions.DataDictionary.Management, new FixedLocalizableString("字典管理")); } private static LocalizableString L(string name) { return LocalizableString.Create<DataDictionaryResource>(name); } }另一个 LocalizableString 就是正常通过 IStringLocalizerFactory 获取的本地化字符串对象。
public class LocalizableString : ILocalizableString { [CanBeNull] public Type ResourceType { get; } [NotNull] public string Name { get; } public LocalizableString(Type resourceType, [NotNull] string name) { Name = Check.NotNullOrEmpty(name, nameof(name)); ResourceType = resourceType; } public LocalizedString Localize(IStringLocalizerFactory stringLocalizerFactory) { return stringLocalizerFactory.Create(ResourceType)[Name]; } public static LocalizableString Create<TResource>([NotNull] string name) { return new LocalizableString(typeof(TResource), name); } }在类型里面定义了一个静态方法,用于目标类型与 KEY 的 LocalizableString 对象,常见于权限定义的地方,在上面的示例代码中有用到过。
2.1.2 本地化资源类型的别名TODO
2.2 本地化的基础设施下文指代的基础设施是指 ABP vNext 为了优雅地实现 Microsoft 本地化接口所构建的一系列组件,ABP vNext 的大部分组件都是基于 Microsoft 提供的抽象体系,也是为了更好地兼容。
2.2.1 模块的启动