1

我正在尝试使用 MEF 和 MVVM 构建 WPF 应用程序。我正在导出我的 ViewModel,但我希望我的 ViewModel 接受构造函数中的模型参数:我将创建一个特定的模型并将其提供给 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
   {
   }

将实例显式添加到容器的另一种方法ComposeExportedValue是使用属性 export。然后,您可以根据需要在属性 getter 中初始化非 MEF 对象:

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

针对comment2进行编辑:首先是警告;ImportingConstructor 和 PartCreator 在 MEF 预览版 8 中似乎不能很好地配合使用,可能是因为 PartCreator 只是一个尚未经过良好测试的示例。使用属性注入来导入 PartCreator 实例。

现在回答你的问题;如果您只想强制 MEF 创建依赖项的多个实例,那么您只需将导入属性设置为[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 回答