2010-06-16 109 views
0

下面是我的問題的演示, 我想創建許多孩子,其中有一個參考他們的父母。MEF導入問題與CreationPolicy

如何編寫import屬性以獲取父引用而不是創建新的父實例?

public partial class MainPage : UserControl 
{ 
    [Import(typeof(Parent))] 
    public Parent Parent1 { get; set; } 

    [Import(typeof(Parent))] 
    public Parent Parent2 { get; set; } 


    public MainPage() 
    { 
     InitializeComponent(); 
     CompositionInitializer.SatisfyImports(this); 
     Parent1.name = "p1"; 
     Parent2.name = "p2"; 
    } 
} 

[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Parent))] 
public class Parent 
{ 
    [Import(typeof(Child))] 
    public Child Child1 { get; set; } 

    [Import(typeof(Child))] 
    public Child Child2 { get; set; } 

    public string name; 
} 


[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Child))] 
public class Child 
{ 
    //how to write the import attribute 
    public Parent Parent { get; set; } 
    public string name; 
} 

回答

0

你可能會遇到的問題,因爲在MEF的組合機制是遞歸的,它通過以圖形的所有對象。你在這裏做的是試圖將一個項目導入另一個項目,另一個項目將嘗試導入第一個項目。您將看到的另一個問題是您指定了NonShared的CreationPolicy,這意味着將爲每個導入創建一個新實例。結合遞歸問題,它是一個完美的內存/性能災難等待發生;)

我會做什麼,是將Parent的CreationPolicy改爲Shared,這樣它不會再組成第二次,也可以是通過子項中的Import屬性進行分配。缺點是你的Parent1和Parent2屬性實際上是Parent的同一個實例。

2

如果我理解你的問題,你不能在這裏進行導入,因爲MEF沒有你在這裏尋找的上下文來執行它。我的建議是將Child.Parent屬性設置爲在Parent中導入的Child。也許在Child1/Child2設置器中將Parent屬性設置爲此。

3

MEF最適合將單獨的模塊鏈接在一起。它有點矯枉過正,將一個意圖處於同一邏輯層次結構中的對象組合起來。

我會打扮的Child屬性來設置父:

[PartCreationPolicy(CreationPolicy.NonShared)] 
[Export(typeof(Parent))] 
public class Parent 
{ 
    private Child _child1; 
    private Child _child2; 

    [Import(typeof(Child))] 
    public Child Child1 
    { 
     get { return _child1; } 
     set { _child1 = value; _child1.Parent = this; } 
    } 

    [Import(typeof(Child))] 
    public Child Child2 
    { 
     get { return _child2; } 
     set { _child2 = value; _child2.Parent = this; } 
    } 

    public string name; 
} 

這樣,只要進口滿足創建Parent類的兒童,Child班都會有自己Parent引用設置爲好。這種鏈接引用的方式是MEF友好和相當標準的。只是不要在兩個方向上做(如果你有一對一的關係),因爲你會得到一個無限循環。

您似乎在設計範圍之外使用MEF。在MEF中,對於每個合同名稱,您可以擁有一個單一引用或多個單一類型的引用。 MEF唯一的上下文是合同名稱(或合同類型的名稱)。

我希望這會有所幫助。