上篇文章我们介绍了
系统国际化改造整体设计思路如下:
今天,我们继续介绍多语言词条服务的设计和实现。
一、多语言词条设计
什么是多语言词条,即代码中需要支持多语言的文本。例如后台提示、前端界面的各类显示元素(Label、Button文字、Tooltips、标题、列表标题等等)。这些内容统一抽象为多语言词条。
多语言词条是产品多语言包的组成部分。支持在不同的语言下,显示对应的文本。
上图中:
I18NTerm代表多语言词条对象,主要描述了多语言词条的各个属性,主要的几个属性有:
/// <summary>
/// 词条的key
/// </summary>
public string Code { get; set; }
/// <summary>
/// 词条的名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 原始文本
/// </summary>
public string OriginalText { get; set; }
/// <summary>
/// 多语言词条子项
/// </summary>
public List<I18NTermItem> TranslateItems { get; set; } = new List<I18NTermItem>();
/// <summary>
/// 隶属的产品
/// </summary>
public string Product { get; set; }
/// <summary>
/// 隶属的关键应用/系统
/// </summary>
/// <remarks>
/// 用于批量打包国际化JS文件
/// </remarks>
public string SubSystem { get; set; }
/// <summary>
/// 隶属的关键应用/系统编号
/// </summary>
/// <remarks>
/// 用于批量打包国际化JS文件
/// </remarks>
public string SubSystemCode { get; set; }
一条词条,包含多个词条子项I18NTermItem,每一个词条子项,都代表了一种语言的翻译结果
public class I18NTermItem : CacheElement
{
///
public string TermID { get; set; }
/// <summary>
/// 语言
/// </summary>
public string Language { get; set; }
/// <summary>
/// 翻译的文本
/// </summary>
public string TranslateText { get; set; }
/// <summary>
/// 用户自定义文本
/// </summary>
public string CustomText { get; set; }
public string GetText()
{
if (string.IsNullOrEmpty(CustomText))
{
return TranslateText;
}
return CustomText;
}
}
二、多语言词条管理服务
有了多语言词条对象后,需要增加其对应的多语言词条管理服务,用于对词条的增删查改
先定义一个多语言词条管理的接口II18NTermManageService
public interface II18NTermManageService
{
void Add(I18NTerm term);
void Remove(string termId);
void AddTerms(List<I18NTerm> terms);
void RemoveTerms(List<string> terms);
void Update(I18NTerm term);
I18NTerm GetTerm(string termId);
List<I18NTerm> GetTerms();
List<I18NTerm> GetTerms(string sourceId);
List<I18NTerm> GetTermsByApplication(string applicationId);
List<I18NTerm> GetTermByConditions(string applicationId, string sourceId = null, string sourceLocation = null, string Dimension1 = null, string Dimension2 = null, string Dimension3 = null);
}
这个接口对应的实现中,可以采用EF完成词条数据的持久化操作,在这里不再详细展示了,大家根据需求自行实现即可。
三、多语言词条查询服务
系统在运行时,需要调用词条服务查询各类词条的翻译文本。因此,抽象一个多语言词条查询服务接口II18NTermService
/// <summary>
/// 词条查询服务接口
/// </summary>
public interface II18NTermService
{
/// <summary>
/// 根据词条编号获取对应的词条翻译
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <returns></returns>
string GetText(string termCode, string defaultText);
/// <summary>
/// 根据词条编号获取对应的词条翻译并格式化输出
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <param name="args">包含零个或多个要格式化的对象的对象数组</param>
/// <returns></returns>
string GetTextFormatted(string termCode, string defaultText, params object\[\] args);
/// <summary>
/// 根据词条编号获取对应的词条翻译
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="language">语言标识</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <returns></returns>
string GetTextWithlanguage(string termCode,string language, string defaultText);
/// <summary>
/// 根据词条编号获取对应的词条翻译并格式化输出
/// </summary>
/// <param name="termCode">词条编号</param>
/// <param name="language">语言标识</param>
/// <param name="defaultText">默认值,如果根据编号找不到词条或者词条对应的翻译将返回默认值</param>
/// <param name="args">包含零个或多个要格式化的对象的对象数组</param>
/// <returns></returns>
string GetTextFormattedWithlanguage(string termCode, string language, string defaultText, params object\[\] args);
/// <summary>
/// 批量获取词条,注意:此接口不能在特来电生产环境使用。
/// </summary>
/// <param name="termCodes"></param>
/// <returns></returns>
Dictionary<string,string> BatchGetText(List<string> termCodes);
}
这个接口的具体实现中,可以增加词条的Redis缓存和内存缓存,调用II18NTermManageService的实现逻辑,从数据库中查询持久化的词条数据。缓存到内存和Redis中, 以提升查询性能。
例如:
///
/// 词条编号
/// 默认值,当找不到对应的词条时将返回默认值
///
///
public string GetText(string termCode, string defaultText)
{
if (string.IsNullOrWhiteSpace(termCode))
throw new ArgumentNullException($"Term Code is null, {termCode}");
if (Teld.Core.Session.Service.AppContext.Current.Language == null)
{
return defaultText;
}
string language = T.Core.Session.Service.AppContext.Current.Language.DisplayCode;
string key = termCode + "&" + language;
if (cache.TryGetValue(key, out var val))
{
return val;
}
var termItem = termManageService.GetTermItem(termCode, language);
if (termItem == null)
{
TermMonitor.NotFound(termCode, language);
return defaultText;
}
else
{
string text = termItem.GetText();
cache\[key\] = text;
return text;
}
}
以上是多语言词条服务的设计和实现。
分享给大家
周国庆
2023/3/11
手机扫一扫
移动阅读更方便
你可能感兴趣的文章