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

MEF中的本地化:导出属性不支持资源(WPF-C#),wpf,plugins,localization,mef,Wpf,Plugins,Localization,Mef,我有一个使用MEF的插件架构的应用程序。对于每个导出的零件,都有一个带有零件名称的属性,我希望转换名称,因为我使用这些字符串来显示列表框(或类似内容)中的可用零件 因此,我尝试在[Export]注释中设置'Name=Strings.SomeText',但出现以下错误: 属性参数必须是常量表达式、typeof表达式或属性参数类型的数组创建表达式 有解决这个问题的方法吗?我发现元数据的使用非常有用(我进行延迟加载),我不想为了翻译一些文本而重新设计所有内容 有什么想法吗?谢谢。不幸的是,您不能直接向

我有一个使用MEF的插件架构的应用程序。对于每个导出的零件,都有一个带有零件名称的属性,我希望转换名称,因为我使用这些字符串来显示列表框(或类似内容)中的可用零件

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

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

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


有什么想法吗?谢谢。

不幸的是,您不能直接向属性提供翻译后的文本,因为属性只能包含在中已知的数据。因此,您需要提供一些编译时常量值,以便以后用于查找翻译后的测试

一种解决方案是将资源名称传递给属性,然后当您想要显示翻译后的文本时,您可以获取资源名称,在资源中查找文本并显示结果

例如,您的属性可能看起来像:

[Export(Name = "SomeText")]
public class MyExport
{
}
然后,当您想显示字符串时,从定义导出的程序集中加载资源,并从加载的资源中提取实际文本。例如,如下所示(借用自):

此解决方案的一个明显缺点是,您失去了使用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
{ 
}
使用此属性可以像这样应用它

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();
var-attribute=typeof(MyClass).GetCustomAttribute();
var text=attribute.ResourceText();

另一种选择是使用

感谢Petrik花时间回答。我没有真正的希望找到一个好的替代方案,在我的情况下,你的答案更复杂,难以实现(出于其他无关的原因).无论如何,我将其标记为答案,请注意,您是否定义了自己的ExportAttribute派生类?如果是这样,那么您可以潜在地捆绑加载其中资源所需的所有代码。确实,我有自己的ExportAttribute,但我不清楚如何在那里应用您的解决方案。您有示例吗?谢谢,我添加了示例。请注意,可能有更好的方法获取数据。此外,我没有添加任何异常处理等。再次感谢您,Petrik!非常好的示例。我发现MEF 2实现了通用导入(请参阅我对原始问题的评论).您好!仅供参考:我刚刚发现MEF 2完全支持我正在寻找的通用导入,但您必须以.NET Framework 4.5为目标才能利用这一点。