2012-01-25 30 views
5

Tôi đang sử dụng phân cấp vùng chứa để kiểm soát thời gian tồn tại của phần IDisposable. Thùng chứa con được đính kèm vào danh mục được lọc có chứa các phần không được chia sẻ. Dưới đây là đoạn mã:Phân cấp vùng chứa MEF và GetExports <T>

[Export(typeof(ITest)), PartCreationPolicy(CreationPolicy.NonShared)] 
class Test : ITest, IDisposable 
{ 
    public void Dispose() {} 
} 

public interface ITest {} 

class Program 
{ 
    static void Main() 
    { 
    // parent container to hold shared disposable parts 
    var cat = new AssemblyCatalog(typeof(Program).Assembly); 
    var parent = new CompositionContainer(cat); 

    // child container to hold non-shared disposable parts 
    var nsCat = CreateNonSharedPartCatalog(cat); 
    var child = new CompositionContainer(nsCat, parent); 

    // no cardinality mismatch exception: exactly one export found 
    var exp = child.GetExport<ITest>(); 

    // lazy exports: count == 2 -- why? 
    var exports = child.GetExports<ITest>(); 
    Console.WriteLine("Exports count = {0}", exports.Count()); 
    } 

    static ComposablePartCatalog 
    CreateNonSharedPartCatalog(ComposablePartCatalog cat) 
    { 
    return new FilteredCatalog(cat, 
     def => def.Metadata.ContainsKey(
     CompositionConstants.PartCreationPolicyMetadataName) && 
     ((CreationPolicy)def.Metadata[ 
     CompositionConstants.PartCreationPolicyMetadataName]) == 
      CreationPolicy.NonShared); 
    } 
} 

(Lớp FilterCatalog giống như được đề cập trong tài liệu MEF).

GetExport không ném ngoại lệ không hợp lệ về số lượng thẻ cho biết không có sự mơ hồ (chính xác một lần xuất được tìm thấy). Nhưng với sự ngạc nhiên của tôi, GetExports() trả về 2 hàng xuất khẩu lười biếng thay vì 1.

Tôi là lỗi này hoặc hành vi này là do thiết kế? Làm cách nào để tôi có thể thiết lập vùng chứa con để GetExports trả về một lần xuất trong mẫu này?

+0

là bất kỳ thứ gì nhập 'ITest'? –

+0

Không, tôi đã đăng đoạn mã hoàn chỉnh tại đây. Chỉ sử dụng và mã lớp FilteredCatalog được loại bỏ. – yallie

Trả lời

2

đây là giới hạn được biết đến của phân cấp vùng chứa trong MEF sử dụng danh mục được lọc. Tôi tin (nhưng không thể xác nhận ngay bây giờ) rằng cài đặt nguồn nhập:

[ImportMany(Source=ImportSource.Local)] 
public IEnumerable<ITest> Tests { get; set; } 

Nên cung cấp hành vi bạn muốn (nhưng chỉ trong MEF2/.NET 4.5 Developer Preview).

Hy vọng điều này sẽ hữu ích!

+0

Cảm ơn bạn đã trả lời! Tính năng này có sẵn trong MEF2 Preview5 được xuất bản tại CodePlex không? – yallie

+0

Tính năng này hoạt động như được mô tả, và thực sự có sẵn trong MEF2 Preview5 được xuất bản tại CodePlex. Tuy nhiên, đặt Source thành ImportSource.Local sẽ chỉ kéo các phần từ vùng chứa con, vì vậy các phần không chia sẻ không thể được nhập theo cách này. Những gì tôi đã cố gắng làm là để có được tất cả các bộ phận xuất khẩu (cả chia sẻ và không chia sẻ), nhưng không có bản sao. – yallie

+0

Ah - Tôi thấy vấn đề, xin lỗi. Cũng trong 4.5 DP, chúng tôi có 'CompositionScopeDefinition' có khả năng xử lý trường hợp này tốt hơn - xem: http://blogs.msdn.com/b/bclteam/archive/2011/12/19/sharing-with-compositionscopedefinition-in -mef2-alok.aspx –

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