序列化可本地化字符串
本文关键字:字符串 本地化 序列化 | 更新日期: 2023-09-27 18:18:52
是否有方便的方法序列化对存储在资源中的字符串的引用。Resx文件(多种语言)。我想稍后访问它(在应用程序可能已经重新启动之后),并以当前活动的语言显示它。
另一个用例是将"资源条目"传递给某个方法,例如显示一条错误消息(用当前活动的语言),同时用英语记录该消息(以便我们可以调试它)。
要记住的一点是,我们并不是只有一个资源。(在这种情况下,我们可以简单地存储Key并使用ResourceManager
实例),但是在复合应用程序中有大量的Key。
有多个用例:一个目的是避免不必要的代码重复。写像ShowMessage(messageKey)
这样的东西(它显示消息并记录它)比写
ShowMessage(Resources.ResourceManager.GetString("Key", CultureInfo.CurrentCulture));
Log(Resources.ResourceManager.GetString("Key", CultureInfo.InvariantCulture));
设置一些局部异常也很有用(这样组件就不必知道关于ShowMessage方法的任何信息)。
在我的情况下,我有一些可序列化的CNC宏,其中我想要有一些可本地化的消息步骤(用户必须在继续之前执行一些手动操作)。在配置宏和执行宏时,语言可能会有所不同。
您可以考虑一些观察者模式的变体,比如使用事件来显示和记录消息的第三方连接。它涉及将以下内容提取到所有程序集使用的低级共享DLL中:
public class UIMessageEventArgs : EventArgs
{
public string Key { get; private set; }
public Func<CultureInfo, string> GetString { get; private set; }
public UIMessageEventArgs(string key, Func<CultureInfo, string> getString)
{
if (key == null || getString == null)
throw new ArgumentNullException();
this.Key = key;
this.GetString = getString;
}
}
public interface IUIMessageService
{
event EventHandler<UIMessageEventArgs> OnMessage;
void ShowMessage(object sender, string key, Func<CultureInfo, string> getString);
}
public sealed class UIMessageService : IUIMessageService
{
static UIMessageService() { instance = new UIMessageService(); }
static UIMessageService instance;
public static UIMessageService Instance { get { return instance; } }
UIMessageService() { }
#region IUIMessageService Members
public event EventHandler<UIMessageEventArgs> OnMessage;
public void ShowMessage(object sender, string key, Func<CultureInfo, string> getString)
{
if (getString == null)
throw new ArgumentNullException("getString");
if (key == null)
throw new ArgumentNullException("key");
var onMessage = OnMessage;
if (onMessage != null)
onMessage(sender, new UIMessageEventArgs(key, getString));
}
#endregion
}
public static class UIMessageExtensions
{
public static void ShowMessage(this ResourceManager resourceManager, string key)
{
if (resourceManager == null)
throw new ArgumentNullException("resourceManager");
if (key == null)
throw new ArgumentNullException("key");
UIMessageService.Instance.ShowMessage(resourceManager, key, c => resourceManager.GetString(key, c));
}
}
我将消息服务设置为单例,因为我怀疑您的所有侦听器都将是单例的。
然后在CNC代码中,您只需调用:
Resources.ResourceManager.ShowMessage("Key");
此外,在c# 6.0中,您应该能够使用nameof
来代替硬编码的属性名称字符串:
Resources.ResourceManager.ShowMessage(nameof(Resources.Key));
顺便说一下,如果您正在实现CAD/CAM相关的宏功能,您可能会考虑记录键字符串而不是不变消息-然后将不变消息作为注释添加到宏中。这样,即使在不变语言中,宏也不会因消息文本的更改(拼写修复)而意外失效。
如果在某些时候需要能够将来自用户的响应记录到宏中,该宏可选地(根据宏作者的意愿)中断交互响应,则可以扩展UIMessageService
模型,以允许通过要注入的消息键返回用户响应的委托。