2012-03-01 27 views
3

我認識到,MEF僅適用於metro風格的應用程序。沒有容器了,那麼如何獲得特定的導出值,如ILogger logger = container.GetExportedValues<ILogger>();? 是否有涵蓋MEF城域版本的任何教程?如何在metro風格應用程序中獲取導出值(MEF)

感謝您的幫助, ENY

+0

你找到一個解決方案?我已經結束了ExportFactory和SatisfyImportsOnce,但我不滿意,我只需要GetExportedValues – 2012-03-13 22:43:29

+0

我正在與開發MEF的地鐵風格應用程序之一的人聯繫。他告訴我,SatisfyImportsOnce目前是撰寫項目的唯一方法。他問我,我記住哪些具體情況不受SatisfyImportOnce支持: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/6aff302d-867a-4921-86ae-b8088c47560f 我發現暫時MEF的一個微小的替代: http://metroioc.codeplex.com/ 希望它也能幫助你。 – Enyra 2012-03-14 17:56:23

+0

我不想使用其他框架,因爲我想在項目之間共享一些代碼。並且儘快在源項目中使用MEF,我想繼續使用它。我的需求不是太大,所以我更願意添加缺少的功能。我將添加我當前的解決方案作爲答案。 – 2012-03-14 19:36:49

回答

1

正如我已經在評論中寫道,我真的不喜歡這種方法,但它是最好的我有什麼了這一刻:

public class CompositionContainer 
{ 
    private readonly CompositionService _service; 

    public CompositionContainer(CompositionService service) 
    { 
     _service = service; 
    } 

    public T GetExportedValue<T>() 
    { 
     var factoryProvider = new FactoryProvider<T>(); 
     _service.SatisfyImportsOnce(factoryProvider); 
     return factoryProvider.Factory.CreateExport().Value; 
    } 

    private class FactoryProvider<T> 
    { 
     [Import] 
     public ExportFactory<T> Factory; 
    } 
} 

和簡單的使用情況可能是這樣之一:

class Program 
{ 
    static void Main() 
    { 
     var catalog = new ApplicationCatalog(); 
     var container = new CompositionContainer(catalog.CreateCompositionService()); 
     for (int i = 0; i < 5; i++) 
     { 
      var dude = container.GetExportedValue<IDude>(); 
      Console.WriteLine(dude.Say()); 
     } 
    } 
    public interface IDude 
    { 
     string Say(); 
    } 

    [Export(typeof(IDude))] 
    public class Eminem : IDude 
    { 
     private static int _instanceNo; 
     private readonly string _phrase; 

     public Eminem() 
     { 
      _instanceNo++; 
      _phrase = string.Join(" ", Enumerable.Range(0, _instanceNo) 
       .Select(_ => "yo!")); 
     } 

     public string Say() 
     { 
      return _phrase; 
     } 
    } 
} 

我不在乎在這個時刻的表現,但我想我會添加工廠供應商或工廠的緩存後

+0

這不是一個壞方法!只是一個可憐的,我們必須編寫這樣的代碼自己:(謝謝老兄。 – Enyra 2012-03-14 19:51:43

2

我猜你已經發現了System.CompononentModel.CompositionSystem.CompononentModel.Composition.Hosting命名空間。

讓我給你一個簡單的例子(看看你是否錯過了什麼)。所有的

首先你需要一個組件注入:

public interface IMefTest 
{ 
    string Message {get;} 
} 

[Export(typeof(IMefTest))] 
public class MefTest: IMefTest 
{ 
    public string Message {get { return "Hello World"; }} 
} 

接下來你需要建立CompositionService(這類似於一個容器,但不完全)。我們希望將它設置在某個可以共同討論的地方,因爲這將是您調用的滿足導入的地方(更多關於此代碼片段的內容)。在這個

static System.ComponentModel.Composition.ICompositionService _compositionService = null; 
public static System.ComponentModel.Composition.ICompositionService CompositionService 
{ 
    get 
    { 
     if (_compositionService == null) 
      ((App)App.Current).loadCompositionService(); 
     return _compositionService; 
    } 
} 

private void loadCompositionService() 
{ 
    // Create a catalog where MEF will search for exported parts to plugin 
    var catalog = new System.ComponentModel.Composition.Hosting.AssemblyCatalog(GetType().GetTypeInfo().Assembly); 
    _compositionService = catalog.CreateCompositionService(); 
} 

只是一點點信息:

我在示例項目陷入這種在App.xaml.cs。我們已經建立了一個彙編目錄,這意味着MEF只會詢問本大會尋找出口的類型。還有其他類型的目錄,我相信你應該能夠將2個或更多的目錄結合在一起。好的,在我的頁面中(順便說一下,我將它構建到MSDN入門文檔中的C#HelloWorld示例中)。

要獲得目錄中某個零件的實例,您只需將屬性添加到要獲取的類並添加一個imports屬性(也有方法可以在構造函數中指定參數,但我試圖保持簡單)

[Import] 
public IMefTest Tester { get; set; } 

在這個例子中,你需要調用的組合服務的SatisfyImportsOnce方法這個類。我這樣做是在構造函數中,我這樣做是這樣的:

if(App.CompositionService != null) 
    App.CompositionService.SatisfyImportsOnce(this); 

(的檢查,以確保該服務存在矯枉過正是我的一部分..它應該存在)。 完成該步驟後,您實際上可以在班級中使用Tester.Message屬性。 MEF中有更多的選擇。我希望這可以幫助你(如果它是你的標誌我作爲答案,因爲我從帳單客戶寶貴的時間爲你做這個)

此外,我知道你想簡單地調用一個容器,並讓它給你支持某種類型的實例。可以用其他形式的MEF來做到這一點,所以我認爲應該可以用WinRT來完成,但我現在確實不確定)。

+0

你好DevTheo,我已經知道了,不幸的是,它不是我正在搜索的。允許容器獲取特定的導出值,但不能滿足任何導入:container.GetExportedValue ();我在Metro MEF上搜索同等功能。 – Enyra 2012-03-03 20:00:26

+0

對不起,我沒有爲你釘.​​.....我不能完全找到你想要的東西(就像我說的需要回到客戶的工作).. 如果我有機會,我會看看稍微遠一點..我有另一個想法,但在我說我有它之前需要嘗試一些東西.. – DevTheo 2012-03-05 17:18:16

+0

我不指望你爲我釘;)我已經有一個想法,我怎麼能做到這一點,但我還沒有足夠的時間呢^^但我不認爲這可以做到沒有一些自定義代碼。 – Enyra 2012-03-05 18:59:15

相關問題