2013-02-03 26 views
1

我已經開始使用MEF。在我的應用程序中,我有一些模型的工廠。 我的工廠有2種創建方法;一個名字作爲參數,另一個是類型。MEF和工廠直接導入創建對象

[Export(typeof(IFactory))] 
[PartCreationPolicy(CreationPolicy.Shared)] 
public class MyFactory : IFactory 
{ 
    public IModel Create(String name) {...} 
    public IModel Create(Type type) {...} 
} 

public class Foo 
{ 
    [Import(typeof(IFactory))] 
    public IFactory Factory { get; set; } 

    public Foo() 
    { 
     IModel modelByName = Factory.Create("name"); 
     IModel modelByType = Factory.Create(typeof(Foo)); 
    } 
} 

當時我已經導入一個工廠,然後調用工廠對象上創建 得到一個模型的時刻。 現在我不知道是否有直接導入模型的方式是這樣的:

[Import(typeof(IModel), Name:"Name")] 
public IModel Model { get; set; } 

編輯---------------------- -----------------------------

的目標將是取代是這樣的:

public class Foo 
{ 
    [Import(typeof(IFactory))] 
    public IFactory Factory { get; set; } 

    public IModel Model { get; set; } 
    public IModel Model1 { get; set; } 

    public Foo() 
    { 
     Model = Factory.Create("Foo"); 
     Model1 = Factory.Create(typeof(Foo1)); 
    } 
} 

惠特這樣的:

public class Foo 
{ 
    //Should internal import a IFactory(singeleton) object 
    //and call the Create(name:String) method on it 
    [Import(typeof(IModel), Name:"Foo")] 
    public IModel Model { get; set; } 

    //Should internal import a IFactory(singeleton) object 
    //and call the Create(type:Type) method on it 
    [Import(typeof(IModel), Type: typeof(Foo1))] 
    public IModel Model1 { get; set; } 
} 

回答

1

您無法將[Import]屬性的參數傳遞給正在導入的類型的方法。

但是我認爲如果你可以的話,你不應該這樣做,因爲做這樣的導入會導致你的類被構建,並且它很可能會被過早地構建。你應該延遲對象的構造,直到它真正需要的時候。通過直接導入,你會失去這種懶惰的行爲。

此外,工廠通常需要一些參數來構造一個類型,但在這裏並不是這樣。如果你絕對需要直接導入,你可以直接導入類型本身,而不是工廠(當然,通過改變工廠的行爲,你將失去稍後通過輕鬆操作構造的選項)。

+0

謝謝你的回答。 ...我想我的問題不夠準確 我不想替換工廠,但我想直接導入Create方法的返回值,所以我不必每次都創建一個因子,只需調用Create就可以了。 – musium

0

您可以將合同名稱添加到導出,然後在導入零件時使用它們。

對於IModel接口:

public interface IModel { } 

您可以使用合同名稱導出實現爲IModel

[Export("Foo1", typeof(IModel))] 
public class Foo1 : IModel { } 

您還可以添加多個出口屬性上的類。這樣你可以滿足這兩種進口(按名稱和類型)。

[Export("Foo2", typeof(IModel))] 
[Export(typeof(Foo2))] 
public class Foo2 : IModel { } 

然後你導入像這樣:

public class Foo 
{ 
    //Import using the contract name. 
    [Import("Foo1", typeof(IModel))] 
    public IModel Model1 { get; set; } 

    //Import using the actual type. 
    [Import(typeof(Foo2))] 
    public IModel Model2 { get; set; } 

    //Import the same model but with contract name instead of type. 
    //This is possible because there are two different exports. 
    [Import("Foo2")] 
    public IModel Model3 { get; set; } 
}  

正如你所看到的你不必在所有使用螞蟻工廠。 MEF將成爲你的工廠。

+0

爲什麼我應該使用動態關鍵字,我知道導入的對象是IModel的類型。 我在尋找的是一種方法來放置一個屬性的屬性,並給這個屬性的字符串或類型作爲參數。此屬性現在應該將該參數傳遞給Create方法,並將Create的返回值存儲在屬性中... 我已經向該問題添加了僞樣本。 – musium

+0

@ user1320170你說得對。我已經更新了我的答案。 –

+0

感謝您的回答。 你是對的;如果我有一個用導出屬性裝飾的類,這將工作。 但是你看過編輯過的問題嗎? 工廠根據給定的字符串或類型(創建(類型:類型),創建(名稱:字符串))做一些重要的事情... 有沒有辦法導入工廠創建的對象(注意:我應該能夠在導入端指定字符串或類型) – musium