文章中的MEF问题

发布于 2024-12-01 07:51:21 字数 1621 浏览 0 评论 0 原文

我在此页面中遇到一个小问题:

http://mef.codeplex.com/ wikipage?title=Parts&referringTitle=Guide

我有这个程序:

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

  public class Program
  {
    [Import]
    public IMessageSender MessageSender { get; set; }

    public static void Main(string[] args)
    {
      Program p = new Program();
      p.Run();
    }

    public void Run()
    {
      Compose();
      MessageSender.Send("Message Sent");
    }

    private void Compose()
    {
      AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
      var container = new CompositionContainer(catalog);
      container.ComposeParts(this);
    }
  }

  public interface IMessageSender
  {
    void Send(string message);
  }

  [Export(typeof(IMessageSender))]
  public class EmailSender : IMessageSender
  {
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

而且我不明白如何编辑它以与此代码一起使用:

  [Export(typeof(IMessageSender))]
  public class EmailSender : IMessageSender {
    ...
  }

  [Export(typeof(IMessageSender))]  
  public class TCPSender : IMessageSender {
    ...
  }

  public class Notifier {
    [ImportMany]
    public IEnumerable<IMessageSender> Senders {get; set;}
    public void Notify(string message) {
      foreach(IMessageSender sender in Senders) 
        sender.Send(message);
    } 
  }

I have a little problem in this page:

http://mef.codeplex.com/wikipage?title=Parts&referringTitle=Guide

I have this program:

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

  public class Program
  {
    [Import]
    public IMessageSender MessageSender { get; set; }

    public static void Main(string[] args)
    {
      Program p = new Program();
      p.Run();
    }

    public void Run()
    {
      Compose();
      MessageSender.Send("Message Sent");
    }

    private void Compose()
    {
      AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
      var container = new CompositionContainer(catalog);
      container.ComposeParts(this);
    }
  }

  public interface IMessageSender
  {
    void Send(string message);
  }

  [Export(typeof(IMessageSender))]
  public class EmailSender : IMessageSender
  {
    public void Send(string message)
    {
      Console.WriteLine(message);
    }
  }

And i don't understand how i can edit it to use with this code:

  [Export(typeof(IMessageSender))]
  public class EmailSender : IMessageSender {
    ...
  }

  [Export(typeof(IMessageSender))]  
  public class TCPSender : IMessageSender {
    ...
  }

  public class Notifier {
    [ImportMany]
    public IEnumerable<IMessageSender> Senders {get; set;}
    public void Notify(string message) {
      foreach(IMessageSender sender in Senders) 
        sender.Send(message);
    } 
  }

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

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

发布评论

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

评论(2

遇到 2024-12-08 07:51:21

我认为您所期望的是这样的:

public interface INotifier
{
  void Notify(string message);
}

[Export(typeof(INotifier))]
public class Notifier : INotifier
{
  [ImportMany]
  public IEnumerable<IMessageSender> Senders { get; set; }

  public void Notify(string message)
  {
    foreach (var sender in Senders)
      sender.Send(message);
  }
}

由此,您可以[Import]一个INotifier的实例:

[Import]
public INotifier Notifier { get; set; }

尽管如此,我确实更喜欢构造函数注入,因为它更好地表达了依赖关系对于你的班级:

[Export(typeof(INotifier))]
public class Notifier : INotifier
{
  private readonly IEnumerable<IMessageSender> _senders;

  [ImportingConstructor]
  public Notifier(IEnumerable<IMessageSender> senders)
  {      
    _senders = senders;
  }

  public void Notify(string message)
  {
    foreach (var sender in _senders)
      sender.Send(message);
  }
}

I think what you are expecting, is something like:

public interface INotifier
{
  void Notify(string message);
}

[Export(typeof(INotifier))]
public class Notifier : INotifier
{
  [ImportMany]
  public IEnumerable<IMessageSender> Senders { get; set; }

  public void Notify(string message)
  {
    foreach (var sender in Senders)
      sender.Send(message);
  }
}

Whereby, you can [Import] an instance of INotifier:

[Import]
public INotifier Notifier { get; set; }

Although, I do prefer constructor injection, as it better expresses dependencies for your class:

[Export(typeof(INotifier))]
public class Notifier : INotifier
{
  private readonly IEnumerable<IMessageSender> _senders;

  [ImportingConstructor]
  public Notifier(IEnumerable<IMessageSender> senders)
  {      
    _senders = senders;
  }

  public void Notify(string message)
  {
    foreach (var sender in _senders)
      sender.Send(message);
  }
}
溺渁∝ 2024-12-08 07:51:21

该示例是为了解释指定接口或抽象类作为导出类型的可能性,即使这也是您的第一个示例中所做的事情。这与导出具体类型不同,例如 [Export(typeof(EMailSender))] 所做的,因为您的导入类必须只知道契约,而不是类的真实名称。此外,它还向您展示了通过 ImportMany 属性导入实现接口的所有导出类型的方法。要在代码中使用它,请使其尽可能简单,即不按照 Matthew 建议引入另一个导入级别或构造函数注入(请查看 http://mef.codeplex.com/wikipage?title=Declaring%20Imports&referringTitle=Guide)您可以简单地在您的 Program 类中修改这些方法:

public void Run()
{
  Notifier nfr = new Notifier();
  Compose(nfr);
  nfr.Notify("Message Sent");
}

private void Compose(Notifier nfr)
{
  AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  var container = new CompositionContainer(catalog);
  container.ComposeParts(nfr);
}

这应该执行的 Send 方法程序集中 IMessageSender 的所有不同实现。

The example is there to explain the possibility to specify an interface or an abstract class as the exported type, even if this is something that is done in your first example, too. This is different from exporting a concrete type, like [Export(typeof(EMailSender))] would have done, since your importing class must know only the contract, not the real name of the class/classes. Furthermore it shows you the way to import all the exported types implementing your interface, through the ImportMany attribute. To use it in your code keeping it as simple as possible, i.e. without introducing another import level or constructor injection as suggested by Matthew (take a look at http://mef.codeplex.com/wikipage?title=Declaring%20Imports&referringTitle=Guide) you could simply modify these methods in your Program class:

public void Run()
{
  Notifier nfr = new Notifier();
  Compose(nfr);
  nfr.Notify("Message Sent");
}

private void Compose(Notifier nfr)
{
  AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
  var container = new CompositionContainer(catalog);
  container.ComposeParts(nfr);
}

This should execute the Send method of all the different implementation of IMessageSender in your assembly.

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