1

MEF と MVVM を使用して WPF アプリケーションを構築しようとしています。ViewModel をエクスポートしていますが、ViewModel がコンストラクターで Model パラメーターを受け入れるようにしたい: 特定のモデルを作成し、それを ViewModel のコンストラクターに提供します。ImportingConstructorAttribute がどのように機能するかを理解しようとしましたが、カスタマイズされたコンストラクターを持つ方法のようです。しかし、私はそれを使用する方法を理解できませんでした。

ImportingConstructorAttribute の使用に関する実際の例を誰かに教えてもらえますか?

前もって感謝します

4

1 に答える 1

5

どうぞ。クラスは、コンストラクターを介してインスタンスをTestインポートします。IFoo

   public class Program
   {
      public static void Main(string[] args)
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         var container = new CompositionContainer(catalog);
         Test test = container.GetExportedValue<Test>();
      }
   }

   [Export]
   public class Test
   {
      private IFoo foo;

      [ImportingConstructor]
      public Test(IFoo foo)
      {
         this.foo = foo;
      }
   }

   public interface IFoo
   {
   }

   [Export(typeof(IFoo))]
   public class Foo : IFoo
   {
   }

コメントに応じて編集:「共有クラスではなく、私たちによって初期化された」とは、属性のない非MEFクラスを手動でインスタンス化し、MEFパーツの依存関係として注入することを意味すると思います。通常、次のようにします。

   public class Program
   {
      public static void Main(string[] args)
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         var container = new CompositionContainer(catalog);

         // create and add non-MEF instance explicitly to container
         var nonMEF = new NonMefClass();
         container.ComposeExportedValue<IFoo>("Test.foo", nonMEF);

         Test test = container.GetExportedValue<Test>();
      }
   }

   [Export]
   public class Test
   {
      private IFoo foo;

      [ImportingConstructor]
      public Test([Import("Test.foo", typeof(IFoo))] IFoo foo)
      {
         this.foo = foo;
      }
   }

   public interface IFoo
   {
   }
   public class NonMefClass : IFoo
   {
   }

インスタンスをコンテナーに明示的に追加する代わりに、プロパティ exportComposeExportedValueを使用することもできます。その後、プロパティ ゲッターで必要に応じて非 MEF オブジェクトを初期化できます。

   public class Bar
   {
      [Export("Test.foo", typeof(IFoo))]
      public IFoo Foo
      {
         get
         {
            return new NonMefClass();
         }
      }
   }

comment2 に応じて編集: 最初に警告。ImportingConstructor と PartCreator は、MEF プレビュー 8 ではうまく連携していないようです。おそらく、PartCreator はまだ十分にテストされていないサンプルに過ぎないためです。PartCreator インスタンスをインポートするには、プロパティ インジェクションを使用します。

あなたの質問に答えましょう。MEF に依存関係の複数のインスタンスを強制的に作成させたいだけの場合は、インポートに a 属性を付けるだけです[Import("Test.foo", typeof(IFoo), RequiredCreationPolicy=CreationPolicy.NonShared)]

インスタンスごとに完全に異なる構成を求めている場合、状況はもう少し複雑になります。複数のコンテナーを設定しない限り、単一のパーツ (つまり、MEF 属性を持つクラス) を持つことはできず、パーツ インスタンスごとに異なる構成にすることはできません。代わりに、そのような場合に行うことは、共通のクラスから継承する複数のパーツを作成することです。次に、目的のコンポジションごとに 1 つのサブクラスを作成します。

   public class Test
   {
      private IFoo foo;

      public Test(IFoo foo)
      {
         this.foo = foo;
      }
   }

   [Export]
   public class TestComposition1 : Test
   {   
      [ImportingConstructor]
      public Test([Import("TestComposition1.foo", typeof(IFoo))] IFoo foo)
         : base(foo)
      {
      }
   }

   [Export]
   public class TestComposition2 : Test
   {   
      [ImportingConstructor]
      public Test([Import("TestComposition2.foo", typeof(IFoo))] IFoo foo)
         : base(foo)
      {
      }
   }

もちろん、これには、限られた数の代替構成を念頭に置いている必要があります。設計時に必要な構成の数を列挙できない場合は、おそらく PartCreator とパーツ メタデータに基づく動的選択を含む、より複雑なものが必要です。

于 2010-02-04T13:13:47.630 に答える