MEF:如何导入具有使用ImportingConstructorFlag标记的构造函数的类

时间:2010-09-06 16:01:45

标签: c# .net .net-4.0 mef

我的问题标题听起来有点困难 - 抱歉。我是MEF的新人: - )。

我的情景:

public class MainClass
{
  [ImportMany(typeof(ITest))]
  private List<ITest> Tests { get; set; }

  public MainClass()
  {
    Init();
  }

  private void Init()
  {
     DirectoryCatalog catalog = new DirectoryCatalog(@"./");
     CompositionContainer container = new CompositionContainer(catalog);
     container.ComposeParts(this);
  }
}



[Export("BirthdayJob")]
[Export(typeof(ITest))]
public partial class BirthdayTest : ITest
{
  [ImportingConstructor]
  public BirthdayUserControl(IParameter parameter)
  {
     InitializeComponent();
     this.Parameter = jobParameter;
  }

   public IParameter Parameter { get; set; }
}

[Export(typeof(IParameter))]
[Export("BirthdayParameter")]
public class BirthdayJobParameter : IParameter
{
   public override string ToString()
   {
       return "Birthday Remember";
   }
}


public interface IParameter : IMefInterface
{

}

public interface IMefInterface
{

}

在通用测试列表中,我应该拥有所有可能的ITest对象以及相关的IParameter对象。不幸的是,通用列表中没有任何项目。

你能帮忙吗?我做错了什么?

提前致谢。

问候,亲

//修改

所以我有一个可编辑的课程来解决我的问题:

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ObjectContracts
{
    public class Program
    {
        static void Main(string[] args)
        {
            var container = new CompositionContainer(new TypeCatalog(typeof (IFoo), typeof (Bar), typeof(Foo)));
            var bar = container.GetExportedValue<Bar>();
            Console.WriteLine(bar.Foo.Message);
            Console.ReadLine();

        }

    }

    [InheritedExport]
    public interface IFoo
    {
        string Message { get; set; }
    }

    [Export]
    public class Bar
    {
        [ImportingConstructor]
        public Bar([Import("Foo")]IFoo foo)
        {
            this.Foo = foo;
        }

        public IFoo Foo { get; set;}
    }

    [Export("Foo")]
    public class Foo : IFoo
    {
        public Foo()
        {
            Message = ":-)";
        }
        public string Message { get; set; }
    }
}

我做错了什么?请帮帮我: - )

问候,帕特里克

4 个答案:

答案 0 :(得分:2)

重点是,如果您在导出中使用合同(在您的情况下为“BirthdayJob”),则还需要在导入中指定该合同。像这样:

[Export("BirthdayJob",typeof(ITest))]
public partial class BirthdayTest : ITest
{
  // class definition
}

你的导入:

public class MainClass
{
  [ImportMany("BirthdayJob",typeof(ITest))]
  private List<ITest> Tests { get; set; }

  // class definition
}

合同的好处在于它们允许您对特定类型的某些对象的实例进行分组,并过滤​​掉特定类型对象的任何不需要的实例。

MEF是最酷的!

[Export("PeopleLivingInEdmontonAlbertaCanada",typeof(IPerson))]
public Person KevinParkinson { get; set; }

答案 1 :(得分:1)

粗略猜测,它可能是您DirectoryCatalog的工作目录(取决于您运行该应用的方式。)

要验证这是否是问题,请替换:

DirectoryCatalog catalog = new DirectoryCatalog(@"./");

使用:

DirectoryCatalog catalog = new DirectoryCatalog(@"<full path to directory>");

或:

AssemblyCatalog catalog = new AssemblyCatalog(typeof(BirthdayTest).Assembly);

答案 2 :(得分:1)

我找到了解决方案。在foo类的导出类中应该是派生接口的引用。具有importconstructor标志的构造函数也应该具有对接口的引用。

 [Export]
    public class Bar
    {
        [ImportingConstructor]
        public Bar([Import("Foo", typeof(IFoo))]IFoo foo)
        //public Bar([Import(typeof(IFoo))]IFoo foo)
        {
            this.Foo = foo;
        }

        public IFoo Foo { get; set;}
    }

    [Export("Foo", typeof(IFoo))]
    public class Foo : IFoo
    {
        public Foo()
        {
            Message = ":-)";
        }
        public string Message { get; set; }
    }

答案 3 :(得分:0)

您是否在任何地方导出IParameter?在您发布的代码中,您不是,这就是生日测试没有被提取的原因。