序列化可本地化的字符串

时间:2015-10-22 12:14:04

标签: c# serialization localization

是否有任何方便的方法来序列化对Resources.resx文件中存储的字符串的引用(多种语言)。我想稍后访问它(在应用程序可能已重新启动之后)并以当前活动的语言显示它。

另一个用例是将“资源条目”传递给某些方法,例如显示错误消息(使用当前活动的语言),同时用英语记录消息(以便我们可以调试它)。

要记住的一点是,我们没有一个Resource.resx文件(在这种情况下我们可以简单地存储密钥并使用ResourceManager实例),但是大量的在复合应用程序中。

有多个用例:一个目的是避免不必要的代码重复。编写类似ShowMessage(messageKey)(显示消息并记录消息)的内容比编写

更方便
ShowMessage(Resources.ResourceManager.GetString("Key", CultureInfo.CurrentCulture));
Log(Resources.ResourceManager.GetString("Key", CultureInfo.InvariantCulture));

这对于获得一些本地化异常也很有用(这样组件就不必了解有关ShowMessage方法的任何信息)。

在我的情况下,我有一些可序列化的CNC宏,我想要一些可本地化的消息步骤(用户必须在继续之前做一些手动操作)。配置宏和执行宏时,语言可能不同。

1 个答案:

答案 0 :(得分:1)

您可以考虑使用事件来显示和记录消息的Observer Pattern,例如Third-party Connect。它涉及将以下内容提取到所有程序集使用的低级共享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模型扩展为允许代表通过消息键返回用户响应以进行注入。