2012-06-11 8 views
5

私はMEFをよく理解していないので、うまくいけば、これはどのように動作するか簡単な修正です。MEF GetExports <T、TMetaDataView> AllowMultiple = Trueで何も返さない

私はMEFを使用してクラスに関する情報とその使用方法を取得しようとしています。私はこれを達成するためにメタデータオプションを使用しています。私のインタフェースと属性は、次のようになります

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; } 
} 

属性で飾られているクラスは、次のようになります。

[ExportMyInterface(typeof(string), 0.1, "whoo data!")] 
[ExportMyInterface(typeof(int), 0.4, "asdfasdf!!")] 
public class DecoratedClass : IMyInterface 
{ 
} 

インポートを使用しようとしている方法は、次のようになります。

private void SomeFunction() 
{ 
    // CompositionContainer is an instance of CompositionContainer 
    var myExports = CompositionContainer.GetExports<IMyInterface, IMyInterfaceInfo>(); 
} 

私の場合、myExportsは常に空です。私のCompositionContainerには、私のカタログに2つのExportDefinitionsがあり、どちらも次のものがあります。ContractName: "MyNamespace.IMyInterface"。 Metadataも、エクスポートごとに正しくロードされます。

AllowMultipleセッターを削除し、1つのエクスポートされた属性のみを含めると、myExports変数にはロードされたメタデータとともに1回のエクスポートが行われるようになりました。

私は間違っていますか?

編集:私が使用している場合は弱い私の輸出が急に満たされ、メタデータを入力:

var myExports = CompositionContainer.GetExports<IMyInterface, IDictionary<string, object>>(); 

任意のアイデアはなぜですか?

答えて

9

AllowMultiple = trueを扱うとき、MEFにいくつかの問題があることが知られています。たとえば、hereのような完全な説明は、AllowMultipleがtrueのときに値が配列で、そのようなものがIMyInterfaceInfoにマップされない、メタデータがディクショナリに保存されているという事実に由来します。

これは私が使用する回避策です。

[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つの属性、標準的な輸出を持っている必要があることを意味し、カスタム属性:まず第一に、あなたの属性は、属性から、ではないExportAttributeから派生する必要があり

[Export(typeof(IMyInterface))] 
[ExportMyInterface(typeof(string), 0.1, "whoo data!")] 
[ExportMyInterface(typeof(int), 0.4, "asdfasdf!!")] 
public class DecoratedClass : IMyInterface 

次にあなたが持っていますインポートされるメタデータのビューを定義します。これにはIDictionaryをパラメータとして持つコンストラクタが必要です。このような何か:http://blogs.microsoft.co:

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]); 
    } 
} 

今、あなたはそれが次の記事を読んだ後、私がやってしまったものだ、成功し

var myExports = CompositionContainer.GetExports<IMyInterface, MyInterfaceInfoView>(); 
+0

うんを呼び出すことができるはずです。私はこの昨日投稿するつもりでしたが、私はあなたのポイントを楽しむことができる前に他のものに引っ張られてしまいました。il/blogs/bnaya/archive/2010/01/29/mef-for-beginner-repeatable-metadata- ! – sohum

+0

クラスを 'ExportAttribute'ではなく' Attribute'から継承させる必要はありません。 'MetadataAttributeAttribute'のポイントは簡潔で簡潔です;-)。カスタムメタデータビューを使用し、手動で配列を処理するだけで私の仕事ができます。ドキュメントから 'AllowMultiple'がメタデータエントリを配列にするのは明らかです。 – binki

関連する問題