MEF GetExports&LT; T,TMetaDataView&GT;用的AllowMultiple没有返回= TRUE [英] MEF GetExports<T, TMetaDataView> returning nothing with AllowMultiple = True
问题描述
我不明白MEF非常好,所以希望这是我怎么想它的工作原理简单的修复。
I don't understand MEF very well, so hopefully this is a simple fix of how I think it works.
我试图使用MEF获取一类的一些信息,应该如何使用。我使用的元数据的选项来尝试实现这一目标。我的接口和属性如下:
I'm trying to use MEF to get some information about a class and how it should be used. I'm using the Metadata options to try to achieve this. My interfaces and attribute looks like this:
public interface IMyInterface
{
}
public interface IMyInterfaceInfo
{
Type SomeProperty1 { get; }
double SomeProperty2 { get; }
string SomeProperty3 { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ExportMyInterfaceAttribute : ExportAttribute, IMyInterfaceInfo
{
public ExportMyInterfaceAttribute(Type someProperty1, double someProperty2, string someProperty3)
: base(typeof(IMyInterface))
{
SomeProperty1 = someProperty1;
SomeProperty2 = someProperty2;
SomeProperty3 = someProperty3;
}
public Type SomeProperty1 { get; set; }
public double SomeProperty2 { get; set; }
public string SomeProperty3 { get; set; }
}
这是装饰与属性的类看起来是这样的:
The class that is decorated with the attribute looks like this:
[ExportMyInterface(typeof(string), 0.1, "whoo data!")]
[ExportMyInterface(typeof(int), 0.4, "asdfasdf!!")]
public class DecoratedClass : IMyInterface
{
}
这是试图使用导入的方法是这样的:
The method that is trying to use the import looks like this:
private void SomeFunction()
{
// CompositionContainer is an instance of CompositionContainer
var myExports = CompositionContainer.GetExports<IMyInterface, IMyInterfaceInfo>();
}
在我的情况下 myExports
总是空空的。在我CompositionContainer中,我有我的目录中的部分有两个 ExportDefinitions
,都与以下 ContractName
:myNameSpace对象.IMyInterface。在元
还装载正确按我的出口。
In my case myExports
is always empty. In my CompositionContainer, I have a Part in my catalog that has two ExportDefinitions
, both with the following ContractName
: "MyNamespace.IMyInterface". The Metadata
is also loaded correctly per my exports.
如果我删除的AllowMultiple
二传手,只包括一个输出属性,在 myExports
变量现在有一个出口其装载的元数据。
If I remove the AllowMultiple
setter and only include one exported attribute, the myExports
variable now has the single export with its loaded metadata.
我在做什么错了?
编辑:如果我使用弱类型的元数据,我出口突然感到满意:
var myExports = CompositionContainer.GetExports<IMyInterface, IDictionary<string, object>>();
任何想法,为什么?
Any ideas why?
推荐答案
据了解,MEF与的AllowMultiple = TRUE打交道时有一些问题
。有关完整的说明,你可以,例如看<一个href=\"http://msmvps.com/blogs/kathleen/archive/2009/09/07/a-fix-we-really-need-in-mef-for-net-4-0.aspx\">here,反正从事实的元数据保存在一个字典,其中值是数组时的AllowMultiple是真的,这样的事情不能在你的IMyInterfaceInfo映射派生的。
It is known that MEF has some problems when dealing with AllowMultiple = true
. For a complete explanation you could for instance look here, anyway it derives from the fact that the metadata are saved in a Dictionary where the values are arrays when AllowMultiple is true, and such a thing can't be mapped on your IMyInterfaceInfo.
这是我用的解决方法。首先,你的属性应该从属性中获得,而不是从ExportAttribute:
This is the workaround I use. First of all your attribute should derive from Attribute, not from ExportAttribute:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ExportMyInterfaceAttribute : Attribute, IMyInterfaceInfo
{
public ExportMyInterfaceAttribute(Type someProperty1, double someProperty2, string someProperty3)
{
SomeProperty1 = someProperty1;
SomeProperty2 = someProperty2;
SomeProperty3 = someProperty3;
}
public Type SomeProperty1 { get; set; }
public double SomeProperty2 { get; set; }
public string SomeProperty3 { get; set; }
}
这意味着,出口类应该有3个属性,一个标准的出口和自定义属性:
This means that the exported class should have 3 attributes, a standard export and your custom attributes:
[Export(typeof(IMyInterface))]
[ExportMyInterface(typeof(string), 0.1, "whoo data!")]
[ExportMyInterface(typeof(int), 0.4, "asdfasdf!!")]
public class DecoratedClass : IMyInterface
然后,你必须定义将要导入的元数据的视图。这必须有一个构造函数的IDictionary的作为参数。事情是这样的:
Then you have to define a view for the metadata which will be imported. This has to have a constructor that takes the IDictionary as parameter. Something like this:
public class MyInterfaceInfoView
{
public IMyInterfaceInfo[] Infos { get; set; }
public MyInterfaceInfoView(IDictionary<string, object> aDict)
{
Type[] p1 = aDict["SomeProperty1"] as Type[];
double[] p2 = aDict["SomeProperty2"] as double[];
string[] p3 = aDict["SomeProperty3"] as string[];
Infos = new ExportMyInterfaceAttribute[p1.Length];
for (int i = 0; i < Infos.Length; i++)
Infos[i] = new ExportMyInterfaceAttribute(p1[i], p2[i], p3[i]);
}
}
现在,你应该能够成功调用
Now you should be able to successfully call
var myExports = CompositionContainer.GetExports<IMyInterface, MyInterfaceInfoView>();
这篇关于MEF GetExports&LT; T,TMetaDataView&GT;用的AllowMultiple没有返回= TRUE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!