介绍
我正在寻找更多定制的解决方案来翻译我的应用程序。我将在获得条目后使用Humanizer
和。问题是首先定义密钥以获取它们。Smart.Format
要求
要求是:
废弃溶液
首先,我丢弃的东西:
我处理问题的想法
现在,我对解决方案的想法看起来是这样(并且受到 C++ 的启发GetText
)
有一个包含键的模板类:
private sealed class Module1Keys : LocalizationKeys<Module1Keys>
{
public static readonly LocalizationKey HelloWorld = DefineKey("/foo", "Hello World!");
public static readonly LocalizationKey HelloWorld2 = DefineKey("/bar", "Hello World2!");
}
并且类 LocalizationKeys 包含一个静态方法,该方法实际上将在简单集合中注册键
public abstract class LocalizationKeys<T> where T : LocalizationKeys<T>
{
protected static LocalizationKey DefineKey(string path, string english)
{
var ret = new LocalizationKey(typeof(T), path, english);
// Following registers localization key in runtime:
Localization.Instance.RegisterLocalizableKey(ret);
return ret;
}
}
在仅剩下来处理这一做法事是名单本地化键生成过程中...这是我在那里打在了墙上。在运行时列出它们很容易,但我不能在构建时运行代码(特别是它可能被构建为共享库)。
也许我想太多了,有更好、更干净的解决方案 - 我不需要坚持使用这个解决方案,但谷歌搜索并没有产生更好的结果......
搞定了。在GetText
次,我们不得不诉诸手动解析代码。
……但是现在,有了 CSharp,我们有了 Roslyn 和 CodeAnalysis API。
连接自定义控制台构建工具,其中包括Microsoft.CodeAnalysis
NuGet 并具有如下代码:
var model = compilation.GetSemanticModel(tree);
var methods = root.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach(var method in methods)
{
if(model.GetSymbolInfo(method).Symbol is IMethodSymbol symbol &&
symbol.ContainingNamespace.Name == "MyProject" &&
symbol.ContainingType.Name == "LocalizationKeys" &&
symbol.Name == "DefineKey")
{
var key = method.ArgumentList.Arguments.FirstOrDefault();
var eng = method.ArgumentList.Arguments.Skip(1).FirstOrDefault();
if(key.Expression is LiteralExpressionSyntax literalKey &&
eng.Expression is LiteralExpressionSyntax literalEng)
{
// "/foo" -> "Hello World!"
// "/bar" -> "Hello World2!"
Console.WriteLine(literalKey + " -> " + literalEng);
}
else
{
// Bonus: detect violation of key definition rule. It is not a literal!
}
}
}
将此控制台工具编译为可执行文件并将其添加为构建后步骤。利润。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句