这些动作仅仅是在注入 Abp 框架的时候所需要执行的一些步骤,如果你要启用多语言,需要在 ASP .NET Core 程序的 Startup 类中的 Configure() 处通过更改 UseAbpRequestLocalization 状态为 True,才会将区域文化识别中间件注入到程序当中。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseAbp(options => { options.UseAbpRequestLocalization = false; //disable automatic adding of request localization }); //...authentication middleware(s) app.UseAbpRequestLocalization(); //manually add request localization //...other middlewares app.UseMvc(routes => { //... }); }其实这里的 UseAbpRequestLocalization() 就已经将上文说的那些 RequestProvider 按照顺序依次注入到 MVC 之中了。
2.代码分析Abp 框架针对本地化处理相关的类型与方法定义都存放在 Abp 库的 Localization 文件夹下。关系还是相对复杂的,这里我们先从其核心的 Abp 库针对于多语言的处理开始讲起。
2.1 多语言模块配置Abp 需要使用的所有信息都是由用户在自己启动模块的 PreInitialize() 当中,通过 ILocalizationConfiguration 进行注入配置。也就是说在 ILocalizationConfiguration 内部,主要是包含了语言,与多语言资源提供者两种重点信息。
public interface ILocalizationConfiguration { // 当前应用程序可配置的语言列表 IList<LanguageInfo> Languages { get; } // 本地化资源列表 ILocalizationSourceList Sources { get; } // 是否启用多语言(本地化) 系统 bool IsEnabled { get; set; } // 以下四个布尔类型的参数主要用于确定当没有找到多语言文本时的处理逻辑,默认都为 True bool ReturnGivenTextIfNotFound { get; set; } bool WrapGivenTextIfNotFound { get; set; } bool HumanizeTextIfNotFound { get; set; } bool LogWarnMessageIfNotFound { get; set; } } 2.2 语言信息当前应用程序能够支持哪一些语言,取决于用户在预加载的时候给多语言模块配置对象分配了哪些语言。通过第 0.1.1 节我们看到用户可以直接通过初始化一个新的 LanguageInfo 对象,将其添加到 Languages 属性之中。
public class LanguageInfo { /// <summary> /// 区域文化代码名称 /// 应该是一个有效的区域文化代码名称,更多的可以通过 CultureInfo 静态类获得所有文化代码。 /// 例如: "en-US" 是北美适用的, "tr-TR" 适用于土耳其。 /// </summary> public string Name { get; set; } /// <summary> /// 该语言默认应该展示的语言名称。 /// 例如: 英语应该展示为 "English", "zh-Hans" 应该展示为 "简体中文" /// </summary> public string DisplayName { get; set; } /// <summary> /// 用于展示的图标 CSS 类名,可选参数 /// </summary> public string Icon { get; set; } /// <summary> /// 是否为默认语言 /// </summary> public bool IsDefault { get; set; } /// <summary> /// 该语言是否被禁用 /// </summary> public bool IsDisabled { get; set; } /// <summary> /// 语言的展示方式是自左向右还是自右向左 /// </summary> public bool IsRightToLeft { get { try { return CultureInfo.GetCultureInfo(Name).TextInfo?.IsRightToLeft ?? false; } catch { return false; } } } public LanguageInfo(string name, string displayName, string icon = null, bool isDefault = false, bool isDisabled = false) { Name = name; DisplayName = displayName; Icon = icon; IsDefault = isDefault; IsDisabled = isDisabled; } }关于语言的定义还是相当简单的,主要参数就是语言的 区域文化代码 与 展示的名称,其余的都可以是可选参数。
小提示:
关于当前系统所支持的区域文化代码,可以通过执行 CultureInfo.GetCultures(CultureTypes.AllCultures); 得到。
2.3 语言管理器Abp 针对语言也提供了一个管理器,接口叫做 ILanguageManager,定义简单,两个方法。
public interface ILanguageManager { // 获得当前语言 LanguageInfo CurrentLanguage { get; } // 获得所有语言 IReadOnlyList<LanguageInfo> GetLanguages(); }实现也不复杂,它内部的实现就是从一个 ILanguageProvider 拿取有哪一些语言数据。
private readonly ILanguageProvider _languageProvider; public IReadOnlyList<LanguageInfo> GetLanguages() { return _languageProvider.GetLanguages(); } // 获取当前语言,其实就是获取的 CultureInfo.CurrentUICulture.Name 的信息,然后去查询语言集合。 private LanguageInfo GetCurrentLanguage() { var languages = _languageProvider.GetLanguages(); // ... 省略了的代码 var currentCultureName = CultureInfo.CurrentUICulture.Name; var currentLanguage = languages.FirstOrDefault(l => l.Name == currentCultureName); if (currentLanguage != null) { return currentLanguage; } // ... 省略了的代码 return languages[0]; }默认实现就是直接读取之前通过 Configuration 的 Languages 里面的数据。