1

MEFを使用して、次のことを行いたいです。

私はWPFシェルを持っています。別の DLL から、MVP トライアドのビューでもある UserControl をインポートしたいシェルに。MVP トライアドが機能する方法は、プレゼンターに、IModel と IView の両方を取り、それらを結び付けるコンストラクターがあることです。したがって、これが機能するためには、MEF が次のことを行う必要があります。

  1. IView 実装を作成する
  2. IModel 実装を作成する
  3. Presenter を作成し、IModel と IView をそのコンストラクターに渡します
  4. IView 実装が表示されたらシェルにインポートする

代わりに、タイプ Exporting IView のみを作成し、それをシェルに渡し、基本的に手順 2 と 3 をスキップします。考えてみるとかなり論理的ですが、どのように MEF にトライアド全体を作成するように指示できますか? IView をお願いします。Shell .dll の他の場所で Presenter やモデルを参照する必要はないので、それを Import として配置することもオプションではありません (とにかく、かなり醜いでしょう :)。

最新の MEF (Preview 2 Refresh) を使用しています。誰?

==アップデート==

私は解決策を見つけ、それについてここでブログを書きました:
Krzysztof Koźmic のブログ - MEF で依存関係のツリーを作成する

しかし、誰かがより良い解決策を思いついたなら、私はもっとうれしいです.**

4

2 に答える 2

2

ここで私の答えを確認してください。

http://codebetter.com/blogs/glenn.block/archive/2008/11/12/mvp-with-mef.aspx

編集:(低品質/LOAとしてフラグが立てられないようにするために、リンクから追加されました

   1: using System.ComponentModel.Composition;
   2: using System.Reflection;
   3: using Microsoft.VisualStudio.TestTools.UnitTesting;
   4:  
   5: namespace MVPwithMEF
   6: {
   7:     /// <summary>
   8:     /// Summary description for MVPTriadFixture
   9:     /// </summary>
  10:     [TestClass]
  11:     public class MVPTriadFixture
  12:     {
  13:         [TestMethod]
  14:         public void MVPTriadShouldBeProperlyBuilt()
  15:         {
  16:             var catalog = new AttributedAssemblyPartCatalog(Assembly.GetExecutingAssembly());
  17:             var container = new CompositionContainer(catalog.CreateResolver());
  18:             var shell = container.GetExportedObject<Shell>();
  19:             Assert.IsNotNull(shell);
  20:             Assert.IsNotNull(shell.Presenter);
  21:             Assert.IsNotNull(shell.Presenter.View);
  22:             Assert.IsNotNull(shell.Presenter.Model);
  23:         }
  24:     }
  25:  
  26:     [Export]
  27:     public class Shell
  28:     {
  29:         private IPresenter _presenter = null;
  30:         
  31:         public IPresenter Presenter
  32:         {
  33:             get { return _presenter; }
  34:         }
  35:  
  36:         [ImportingConstructor]
  37:         public Shell(IPresenter presenter)
  38:         {
  39:             _presenter = presenter;
  40:         }
  41:     }
  42:  
  43:     public interface IModel
  44:     {
  45:     }
  46:  
  47:     [Export(typeof(IModel))]
  48:     public class Model : IModel
  49:     {
  50:         
  51:     }
  52:  
  53:     public interface IView
  54:     {
  55:     }
  56:  
  57:     [Export(typeof(IView))]
  58:     public class View : IView
  59:     {
  60:     }
  61:  
  62:     public interface IPresenter
  63:     {
  64:         IView View { get;}
  65:         IModel Model { get; }
  66:     }
  67:  
  68:     [Export(typeof(IPresenter))]
  69:     public class Presenter : IPresenter
  70:     {
  71:  
  72:         private IView _view;
  73:         private IModel _model;
  74:  
  75:         [ImportingConstructor]
  76:         public Presenter(IView view, IModel model)
  77:         {
  78:             _view = view;
  79:             _model = model;
  80:         }
  81:  
  82:         public IView View
  83:         {
  84:             get { return _view; }
  85:         }
  86:  
  87:         public IModel Model
  88:         {
  89:             get { return _model; }
  90:         }
  91:  
  92:     }
  93: }

では、ここで何が起こっているのでしょうか。

シェルにプレゼンターが注入されます。プレゼンターはビューとモデルを注入されます。ここのすべてはシングルトンですが、そうである必要はありません。

2つの例の違いは、プレゼンターがビューではなくシェルに注入されていることです。プレゼンターがビューを作成している場合は、最初にビューを取得することはできません(彼が行っていたように)。そうしないと、プレゼンターは作成されません。ええ、あなたはそれをすることができます、しかしあなたはそれを少しハッキングすることになります。クリーナーとは、プレゼンターを挿入してIViewを公開することです。これはPrismで行いましたが、非常にうまく機能しました。

于 2008-11-12T23:08:57.373 に答える
1

ブログ投稿で概説した方法は、MEF を利用するための完全に有効な方法です。これはネストされた構成であり、設計中は常にコンテナーが決定者であることを念頭に置くことをお勧めします。そのため、プラグイン/エクステンダーのベンダーとして、「エクスポート」しているサービスに焦点を当て、重要なこととして、何を修理する必要があるか、または「インポート」する必要があるかについて心配する必要はありません (この点については、最後のドロップでいくつかの問題がありますが、それについては楽観的であると十分に聞いています)。

したがって、ネストされた構成では、いくつかの外部サービスが必要になる場合がありますが、その時点でいくつかを提供することもできます。構成を行うと、すべてがまとめられます。

この考え方を示す 2 つの例を含むブログ投稿があります。

http://www.sidarok.com/web/blog/content/2008/09/26/what-is-this-managed-extensibility-framework-thing-all-about.html

また、dll をドロップしてその中のタイプを監視するには、DirectoryPartCatalog を使用してそのフォルダーを監視します。

また、同じコントラクトに対して複数のエクスポートが存在するシナリオに注意し、提供されたメタデータから適切なエクスポートを判断する必要があります。

于 2008-11-12T22:01:55.090 に答える