2012-03-01 8 views
3

メトロスタイルのアプリケーションではMEFが制限されています。もうコンテナはないので、具体的なエクスポートされた値を得るにはどうすればILogger logger = container.GetExportedValues<ILogger>();? MEFのメトロ版をカバーするチュートリアルはありますか?メトロスタイルのアプリケーションでエクスポートされた値(MEF)を取得する方法

私はあなたがSystem.CompononentModel.CompositionSystem.CompononentModel.Composition.Hosting名前空間を発見した推測しているヘルプ、 ENY

+0

あなたが解決策を見つけた私は、工場・プロバイダーや工場のキャッシュを追加しますね?私はExportFactoryとSatisfyImportsOnceで終わったが、私はそれに満足していない、ただGetExportedValuesが必要 –

+0

私はメトロスタイルのアプリのMEFを開発している人の1人と連絡を取り合っている。彼は、SatisfyImportsOnceは現在のところアイテムを構成する唯一の方法だと私に言った。彼は、SatisfyImportOnceによってサポートされていない具体的なシナリオを教えてくれました。 http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/6aff302d-867a-4921-86ae-b8088c47560f 当面、MEFへの小さな代替案が見つかりました。 http://metroioc.codeplex.com/ また、あなたに役立つことを願っています。 – Enyra

+0

私はプロジェクト間でいくつかのコードを共有したいので、他のフレームワークを使用したくありません。すぐに私はすでにソースプロジェクトでMEFを使用していますが、私はそれを使い続けたいと思います。私のニーズはそれほど大きくないので、欠けている機能を追加することを好みます。現在のソリューションを回答として追加します。 –

答えて

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

とシンプルなユースケースは、このかもしれません1:

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

2

いただきありがとうございます。

ここでは簡単な例を示します(何か不足しているかどうかを確認してください)。

あなたは注入するためのコンポーネントを必要とするすべてのファースト:

public interface IMefTest 
{ 
    string Message {get;} 
} 

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

次は(これはコンテナに似ていますが、正確ではない)CompositionServiceを設定する必要があります。私たちはこれをどこかに設定して、一般的に話すことができるようにしたいのです。これは、あなたがインポートを満たすために呼び出す場所です(この後のコードスニペットで詳しく説明します)。

私は私のサンプルプロジェクトでApp.xaml.csでこれを立ち往生:この上

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

は、ほんの少しの情報。私たちは、MEFが輸出されたタイプを探すこのアセンブリだけを調べることを意味するアセンブリカタログを作成しました。他のタイプのカタログもありますし、2つ以上のカタログを組み合わせることができるはずです。

[OK]を私のページ(BTW、私はこれをC#HelloWorldの例には、MSDNのGetting Startedドキュメントから作成しました)。

カタログ内の部品のインスタンスを取得するには、取得するクラスにプロパティを追加し、import属性を追加する必要があります(コンストラクタで引数を指定する方法もありますが私はこの例では)

[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

+0

申し訳ありません私はあなたのためにそれを釘付けしていませんでした...私はまさにあなたが望んでいたものを正確に見つけることができませんでした(そして、私は顧客の仕事に戻る必要があると言ったように) 私はチャンスを得る私は別のアイデアを持っていますが、私はそれを持っていると言う前に何かを実験する必要があります。 – DevTheo

+0

私はあなたが私のためにそれを釘付けするとは思わない;)私はすでに私がそれを行うことができるアイデアを持っていますが、まだ十分な時間がありません^^しかし、私はそれがいくつかのカスタムコードなしで行うことができるとは思わない。 – Enyra

関連する問題