0

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

// 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")
4

1 回答 1

4

您可以使用下面的 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;
    }
#>
于 2013-07-08T13:30:47.687 回答