【问题标题】:MEF Import - Object reference errorMEF 导入 - 对象引用错误
【发布时间】:2010-08-04 22:06:41
【问题描述】:

我试图弄清楚为什么我的一个对象似乎不满足其导入。我认为这可能是我使用 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 不满意。

任何关于组成部分以及如何满足 Imports 的帮助或指示将不胜感激。

【问题讨论】:

    标签: mef


    【解决方案1】:

    我本人对 MEF 还很陌生,但我在这里看到的是:您没有将 IMessageService 作为主应用程序的实例 - 相反,它位于一个单独的对象 ServiecManager 上,您在container.ComposeParts 被调用后动态创建...

    我的猜测:MEF 没有机会满足对 ServiceManager 的导入,因为在组合时该对象不存在。

    建议:将IMessageService 实例添加到您的主应用程序并让MEF 处理导入,然后将该实例传递给您的ServiceManager - 类似这样:

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

    我很确定如果您这样做,那么 MEF 将能够满足导入,并且您将拥有自己的 MessageService 实例,然后您可以将其传递给 ServiceManager

    【讨论】:

    • 谢谢。最后我做了类似的事情,我在我的 ServiceManager 上放置了一个 Export 属性,然后将它导入到我的 Program 类中。我想我只是想了解容器如何组成它们的部分以及何时组成。 service.core 项目应该加载自己的容器并使用它,还是应该只是应用程序中的一个容器。很难找到关于整个框架的适当文档来解释这一点。
    • 不是 100% 确定要告诉你什么 - 我对这些东西也很陌生 :-) 但我的理解是:使用 container.ComposeParts(this),你告诉 MEF 解决所有问题“this”中的引用 - “程序”类。这不会扩展到您稍后创建的 ServiceManager(在 MEF 组成部分之后)。也许您还需要明确地调用 ServiceManager 上的 ComposeParts - 再次,不是 100% 确定......
    • 是的,我认为这也有效。我还看到了这篇较早的帖子,它描述了我在上面遇到的相同问题:stackoverflow.com/questions/1845892/… 我想我需要更多地了解构图。再次感谢。
    猜你喜欢
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 2012-01-07
    相关资源
    最近更新 更多