【问题标题】:Localization in MEF: export attribute does not support a resource (WPF - C#)MEF 中的本地化:导出属性不支持资源 (WPF - C#)
【发布时间】:2012-12-03 17:19:19
【问题描述】:

我有一个使用 MEF 的具有插件架构的应用程序。对于每个导出的部件,都有一个带有部件名称的属性,我希望翻译名称,因为我使用这些字符串来显示 ListBoxes(或类似)中的可用部件。

所以,我尝试在 [Export] 注释中设置“Name = Strings.SomeText”,但出现以下错误:

“属性参数必须是属性参数类型的常量表达式、typeof表达式或数组创建表达式”

有解决办法吗?我发现元数据的使用非常有用(我会延迟加载),我不想为了翻译一些文本而重新设计所有内容。

有什么想法吗?谢谢。

【问题讨论】:

  • 仅供参考:我刚刚发现 MEF 2 完全支持我正在寻找的通用导入,但您必须以 .NET Framework 4.5 为目标才能利用这一点。

标签: wpf plugins localization mef


【解决方案1】:

很遗憾,您不能直接将翻译后的文本提供给属性,因为属性只能包含compile time 已知的数据。因此,您需要提供一些编译时间常数值,以便稍后用于查找已翻译的测试。

一种解决方案是将资源名称传递给属性。然后当你想显示翻译后的文本时,你抓住资源名称,在资源中查找文本并显示结果。

例如,您的属性可能类似于:

[Export(Name = "SomeText")]
public class MyExport
{
}

然后,当您想要显示字符串时,您从定义导出的程序集中加载资源,并从加载的资源中提取实际文本。比如这样(借自another answer):

var assembly = typeof(MyExport).Assembly;

// Resource file.. namespace.ClassName
var rm = new ResourceManager("MyAssembly.Strings", assembly);

// exportName contains the text provided to the Name property 
// of the Export attribute
var text = rm.GetString(exportName);

此解决方案的一个明显缺点是您失去了使用 Strings.SomeText 属性所获得的类型安全性。

--------- 编辑 ---------

为了更容易获得翻译文本,您可以创建ExportAttribute 的派生词,它需要足够的信息来提取翻译文本。例如自定义ExportAttribute 可能如下所示

public sealed class NamedExportAttribute : ExportAttribute
{
    public NamedExportAttribute()
        : base()
    { 
    }

    public string ResourceName
    {
        get;
        set;
    }

    public Type ResourceType
    {
        get;
        set;
    }

    public string ResourceText()
    {
        var rm = new ResourceManager(ResourceType);
        return rm.GetString(ResourceName);
    }
}

使用此属性,您可以像这样应用它

[NamedExport(
    ResourceName = "SomeText", 
    ResourceType = typeof(MyNamespace.Properties.Resources))]
public sealed class MyClass
{ 
}

最后,当您需要获取翻译文本时,您可以这样做

var attribute = typeof(MyClass).GetCustomAttribute<NamedExportAttribute>();
var text = attribute.ResourceText();

另一种选择是使用DisplayAttribute

【讨论】:

  • 感谢 Petrik 抽出时间来回答。我没有真正希望找到一个好的替代方案,在我的情况下,您的答案实施起来更复杂(出于其他不相关的原因)。无论如何,我将其标记为答案,问候,
  • 您是否定义了自己的 ExportAttribute 派生类?如果是这样,那么您可能会捆绑在那里加载资源所需的所有代码。
  • 确实,我有自己的 ExportAttribute,但我不清楚如何在那里应用您的解决方案。你有一个例子吗?谢谢
  • 我已经添加了示例。请注意,可能有更好的方法来获取数据。另外我还没有添加任何异常处理等。
  • 再次感谢您,Petrik!很好的例子。我发现 MEF 2 实现了通用导入(请参阅我对原始问题的评论)。问候!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
  • 2017-10-05
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
相关资源
最近更新 更多