MEF导入 - 对象引用错误

时间:2010-08-04 22:06:41

标签: mef

我试图找出为什么我的一个物体似乎不满足其导入。我想这可能是我使用container.ComposeParts()函数的方式,但我找不到有关它的文档。

我有四个项目 MEF.Service.Contracts
MEF.Service.Messaging(实施合同)
MEF.Service.Core
MEF.Service.Console

MEF.Service.Contracts包含一个名为IMessageService的简单接口,其中包含一个函数

public interface IMessageService
{
    void SendMessage(string message);
}

MEF.Service.Messaging有上述

的一个实现
[Export(typeof(IMessageService))]
public class ConsoleMessageService : IMessageService
{
    #region IMessageService Members

    public void SendMessage(string message)
    {
        Console.WriteLine(message);
    }

    #endregion
}

MEF.Service.Core有一个名为ServiceManager的类,用于导入可用的服务。在此示例中,IMessageService

public class ServiceManager
{
    [Import]
    public IMessageService MessageService { get; set; }
}

最后,在MEF.Service.Console应用程序项目中,我使用DirectoryCatalog创建MEF容器。然后我创建一个ServiceManager实例并调用它的MessageService属性 但是此时它失败并出现对象引用错误。

以下是MEF.Service.Console项目中的代码

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

    public void Run()
    {
        Compose();

        ServiceManager manager = new ServiceManager();
        manager.MessageService.SendMessage("Test Message");

        Console.ReadLine();
    }

    private void Compose()
    {
        var catalog = new DirectoryCatalog(@".\");
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }
}

MEF.Service.Console引用了其他三个项目,只是为了确保dll在运行时位于同一个文件夹中。

我在初始化之后检查了目录和容器,它确实包含我的ConsoleMessageService导出作为一部分。

我正在试图找出为什么我的ServiceManager中的[Import] MessageService没有得到满足。

任何关于组成零件的帮助或指示以及进口如何得到满足将不胜感激。

1 个答案:

答案 0 :(得分:1)

我自己对MEF很新,但我在这里看到的是:你没有将IMessageService作为主应用程序的实例 - 相反,它是在一个单独的对象上{{1} },在调用ServiecManager之后动态创建 ...

我的猜测:MEF没有机会满足container.ComposeParts上的导入,因为在合成时该对象不在。

建议:在主应用中添加ServiceManager实例,让MEF处理导入,然后将该实例传递到IMessageService - 如下所示:

ServiceManager

我很确定如果你这样做,那么MEF将能够满足导入,你将拥有一个class Program { static void Main(string[] args) { Program p = new Program(); p.Run(); } [Import] IMessageService MessageService { get; set; } public void Run() { Compose(); ServiceManager manager = new ServiceManager(MessageService); manager.MessageService.SendMessage("Test Message"); Console.ReadLine(); } private void Compose() { var catalog = new DirectoryCatalog(@".\"); var container = new CompositionContainer(catalog); container.ComposeParts(this); } } 实例,然后你可以将其传递给MessageService