您可以使用下面的 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;
}
#>