如何通过设置路径获取插件

时间:2012-02-28 06:55:01

标签: mef

我创建了控制台c#项目。在代码中我制作了一个模块。我的代码看起来像这样。

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

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

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

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

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

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

它完美无缺。但现在我在我的解决方案中添加了一个新项目,并在其中添加了模块 AnotherProject-> EmailSender.cs

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

现在在主控制台程序中,我改变了一些代码。

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

但现在我运行这个程序。它没有加载模块。主程序中的MessageSender为null。我做错了什么。

1 个答案:

答案 0 :(得分:0)

您需要检查一些事项:

  1. 您是否正确引用了程序集?
  2. 默认情况下,DirectoryCatalog使用搜索模式*.dll。因为您有一个使用.exe扩展名的控制台应用程序,所以DirectoryCatalog中的导出将不会被默认搜索模式拾取。您可能希望使用AggregateCatalog,传递DirectoryCatalog*.dll),以及另一个DirectoryCatalog*.exe)或{{{ 1}},条目汇编。
  3. 您目前有一个AssemblyCatalog,其中您最终可能会有多个[Import],但您没有说明已将[Export(typeof(IMessageSender))]移至该课程库,只是你已经创建了一个 new ,这意味着你可能最终得到一个基数不匹配的地方,它期望一个错误的导入,你有很多出口。这将显式抛出异常,即使找不到EmailSender的单个实例也会发生这种情况,因为您的IMessageSender属性未设置为允许默认值,其中不能提供任何部分。如果您需要容错,可以使用[Import]
  4. 顺便说一句......以上代码无法编译,我认为这只是一个例子而不是当前代码的复制粘贴?

    [Import(AllowDefault = true)]

    您正在将消息重新发送到public void SendMessage(string message) { return message; } 方法 - 这是无法完成的,这也意味着void无法正确实施EmailSender。不要太烦恼,因为我认为这不仅仅是一个实际代码。