2012-06-11 23 views
5

Tôi không hiểu MEF rất tốt, vì vậy hy vọng đây là một cách khắc phục đơn giản về cách tôi nghĩ nó hoạt động.MEF GetExports <T, TMetaDataView> không trả lại gì với AllowMultiple = True

Tôi đang cố gắng sử dụng MEF để nhận một số thông tin về một lớp học và cách sử dụng nó. Tôi đang sử dụng các tùy chọn Siêu dữ liệu để cố gắng đạt được điều này. giao diện và thuộc tính của tôi trông như thế này:

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

Lớp được trang trí với các thuộc tính như sau:

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

Phương pháp mà đang cố gắng sử dụng nhập khẩu như sau:

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

Trong trường hợp của tôi myExports luôn trống. Trong CompositionContainer của tôi, tôi có một phần trong danh mục của tôi có hai ExportDefinitions, cả hai đều có ContractName: "MyNamespace.IMyInterface" sau đây. Metadata cũng được tải chính xác cho mỗi lần xuất của tôi.

Nếu tôi xóa thiết lập AllowMultiple và chỉ bao gồm một thuộc tính đã xuất, biến số myExports hiện có một lần xuất với siêu dữ liệu đã tải của nó.

Tôi đang làm gì sai?

EDIT: Nếu tôi sử dụng yếu gõ Metadata, xuất khẩu của tôi là bất ngờ hài lòng:

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

Bất cứ ý tưởng tại sao?

Trả lời

9

Được biết, MEF có một số vấn đề khi giao dịch với AllowMultiple = true. Đối với một lời giải thích đầy đủ bạn có thể ví dụ nhìn here, dù sao nó xuất phát từ thực tế là siêu dữ liệu được lưu trong một từ điển, nơi các giá trị là mảng khi AllowMultiple là đúng, và một điều như vậy không thể được ánh xạ trên IMyInterfaceInfo của bạn.

Đây là cách giải quyết mà tôi sử dụng. Trước hết thuộc tính của bạn nên xuất phát từ thuộc tính, không phải từ 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; } 
} 

Điều này có nghĩa rằng lớp được xuất nên có 3 thuộc tính, một tiêu chuẩn xuất khẩu và các thuộc tính tùy chỉnh của bạn:

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

Sau đó, bạn có để xác định chế độ xem cho siêu dữ liệu sẽ được nhập. Điều này phải có một hàm tạo lấy IDictionary làm tham số. Một cái gì đó như thế này:

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

Bây giờ bạn sẽ có thể gọi thành công

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

Yep, đó là những gì tôi đã kết thúc làm, sau khi đọc bài viết sau đây: http://blogs.microsoft.co. il/blogs/bnaya/archive/2010/01/29/mef-cho-beginner-repeatable-metadata-part-9.aspx Tôi sẽ đăng bài này ngày hôm qua nhưng đã bị kéo vào những thứ khác trước khi tôi có thể kết thúc để tận hưởng điểm của bạn ! – sohum

+0

Không cần phải tạo lớp kế thừa từ 'Thuộc tính' thay vì' ExportAttribute'. Điểm của 'MetadataAttributeAttribute' là ngắn gọn và concision ;-).Chỉ cần sử dụng chế độ xem siêu dữ liệu tùy chỉnh và xử lý thủ công các mảng hoạt động cho tôi. Nó không phải là rõ ràng từ các tài liệu mà 'AllowMultiple' gây ra các mục siêu dữ liệu để trở thành mảng, rất lạ… – binki

Các vấn đề liên quan