MEF中的本地化:export属性不支持资源(WPF - C#)

时间:2012-12-03 17:19:19

标签: wpf plugins localization mef

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

所以,我试着设置' Name = Strings.SomeText"在[导出]注释中,但我收到以下错误:

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

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

有什么想法吗?感谢。

1 个答案:

答案 0 :(得分:3)

很遗憾,您无法直接向属性提供已翻译的文本,因为属性只能包含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