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

发布于 2024-09-18 02:04:29 字数 2203 浏览 10 评论 0原文

我的问题标题听起来有点困难 - 抱歉。我是 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; }
    }
}

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

问候,帕特里克

My question title sounds a little bit difficult - sorry. I'm new in MEF :-).

My scenario:

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
{

}

In the generic list of test, I should have all possible ITest objects with the associated IParameter object. Unfortunately, there aren't any items in the generic list.

Can you help? What did I do wrong?

Thanks in advance.

Regards, pro

//Edit

So I have a compilable Class for my problem :

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

What do I do wrong? Please help me :-)

Regards, patrick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寄离 2024-09-25 02:04:30

关键是,如果您在导出中使用合同(在您的例子中为“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; }

The point is that if you use a contract (in your case "BirthdayJob") in your export, you need to specify that in your import as well. Like so:

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

And your import:

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

  // class definition
}

The great thing about contracts is that they allow you to group instances of certain objects of a specific type and filter out any unwanted instances of objects of a specific type.

MEF is the coolest!

[Export("PeopleLivingInEdmontonAlbertaCanada",typeof(IPerson))]
public Person KevinParkinson { get; set; }
相守太难 2024-09-25 02:04:30

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

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

I've found the solution. In the export class of the foo class should be a reference of the derived interface. The constructor which have the importingconstructor flag should have also a reference to the interface.

 [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; }
    }
七分※倦醒 2024-09-25 02:04:30

大胆猜测,它可能是您的 DirectoryCatalog 的工作目录(取决于您运行应用程序的方式。)

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

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

为:

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

或:

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

Taking a wild guess, it is possibly the working directory of your DirectoryCatalog (depending on how you run the app.)

To verify that this is the problem, replace:

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

With either:

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

or:

AssemblyCatalog catalog = new AssemblyCatalog(typeof(BirthdayTest).Assembly);
浪推晚风 2024-09-25 02:04:30

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

Are you exporting IParameter anywhere? In the code you posted, you are not, and this is why the Birthday test isn't being picked up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文