【问题标题】:Is there a way to avoid using hard-coded resw keys with the windows store app ResourceLoader?有没有办法避免在 Windows 商店应用程序 ResourceLoader 中使用硬编码的 resw 键?
【发布时间】:2013-07-08 13:30:47
【问题描述】:

有没有办法避免对 Windows 商店应用程序中的 resw 文件中包含的全球化字符串使用硬编码键?即

// I have to use a hard-coded string key, which may violate the
// DRY principle to gain access to the translation from C#:
var translation =
    Windows.ApplicationModel.Resources.ResourceLoader.GetString("MyStringKey/Text")

【问题讨论】:

    标签: c# windows-store-apps translation t4 globalization


    【解决方案1】:

    您可以使用下面的 T4 模板自动生成围绕您的 resw 文件的 C# 包装器。这意味着您无需在代码中乱扔魔术字符串资源键来访问 C# 的翻译 - 然后您的所有键都知道在编译时有效,而不是在运行时有效。模板生成如下代码:

    internal static class Translation
    {
        public static ResourceLoader ResourceLoader { get; private set; }
    
        static Translation()
        {
            ResourceLoader = new ResourceLoader();
        }
    
        public static string MyFirstString
        {
            get { return ResourceLoader.GetString("MyFirstString/Text"); }
        }
    }
    

    这是由以下 T4 模板生成的:

    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ assembly name="System.Core" #>
    <#@ assembly name="System.Xml" #>
    <#@ assembly name="System.Xml.Linq" #>
    <#@ assembly name="EnvDTE" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Xml.Linq" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="Microsoft.CSharp" #>
    <#@ import namespace="EnvDTE" #>
    <#@ output extension=".cs" #>
    <#
        DTE env = GetVSEnvironment();
        var inputFilePath = @"en-GB\Resources.resw";
        var provider = new CSharpCodeProvider();
        string className = CreateClassName(provider);
    
        SetCurrentDirectory();
        if (File.Exists(inputFilePath)) {
    #>
    //------------------------------------------------------------------------------
    // <auto-generated>
    // This code was generated by a resource generator.
    // </auto-generated>
    //------------------------------------------------------------------------------
    using Windows.ApplicationModel.Resources;
    
    namespace <#= GetNamespace() #> {
        internal static class <#= className #> {
            public static ResourceLoader ResourceLoader { get; private set; }
    
            static <#= className #>() {
                ResourceLoader = new ResourceLoader();
            }
    <#
            foreach (string name in GetResourceKeys(inputFilePath)) {
    #>
            public static string <#= provider.CreateEscapedIdentifier(name.Replace(".Text", String.Empty).Replace(".Content", String.Empty).Replace(".FlowDirection", string.Empty)) #> {
                get { return ResourceLoader.GetString("<#= name.Replace(".Text", "/Text").Replace(".Content", "/Content").Replace(".FlowDirection", "/FlowDirection") #>"); }
            }
    <#
            }
    #>
        }
    }
    <#
        } else {
            throw new FileNotFoundException(String.Format("Unable to find Resource file: {0}", inputFilePath)); 
        } 
    #>
    <#+
        private DTE GetVSEnvironment() {
            DTE env = null;
            var provider = Host as IServiceProvider;
            if (provider != null) {
                env = provider.GetService(typeof(DTE)) as DTE;
            }
    
            if (env == null) {
                throw new InvalidOperationException("Template must be executed from Visual Studio");
            }
    
            return env;
        }
    
        private void SetCurrentDirectory() {
            Directory.SetCurrentDirectory(Host.ResolvePath(""));
        }
    
        private string CreateClassName(CSharpCodeProvider provider) {
            string name = Path.GetFileNameWithoutExtension(Host.TemplateFile);
            return provider.CreateEscapedIdentifier(name);
        }
    
        private string GetNamespace() {
            return Host.ResolveParameterValue("directiveId", "namespaceDirectiveProcessor", "namespaceHint");
        }
    
        private static IEnumerable<string> GetResourceKeys(string filePath) {
            XDocument doc = XDocument.Load(filePath);
            var rootElement = doc.Root.Elements().SingleOrDefault(x => x.Name == "root");
            if (rootElement == null)
            {
                throw new InvalidOperationException("No root element was found");
            }
            var dataElements = rootElement.Elements("data").ToList();
            var resourceKeys = dataElements.Select(e => e.Attribute("name").Value).ToList();
            return resourceKeys;
        }
    #>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      相关资源
      最近更新 更多