MEF导入为空

时间:2013-03-02 22:44:32

标签: c# dependency-injection null mef

我有一个无效的导入 - 该对象为null。最初它是一个ImportMany,但我将其简化为导入以尝试识别问题,但我没有成功这样做。

我已经浏览了这个网站和Google,并遵循了主要想法:

  • 不要自己实例化该类,让MEF执行此操作,否则调用container.getExport() - 仍然无法正常工作
  • 在包含[Import]属性的类上放置[Export],否则它将不会被容器组合过程选中(在调试时确认)。

我的代码设置如下(为了紧凑而简化):

Assembly1

public class MyBootstrapper
{
    //Automatically called by ExcelDna library, I do not instantiate this class
    public void AutoOpen()
    {
        var ac1 = new AssemblyCatalog(typeof(XLHandler).Assembly);
        var ac2 = new AssemblyCatalog(typeof(MyComponent).Assembly);

        var agc = new AggregateCatalog();
        agc.Catalogs.Add(ac1);
        agc.Catalogs.Add(ac2);

        var cc = new CompositionContainer(agc);

        try
        {
            cc.ComposeParts(this);
        }
        catch (CompositionException exception) {}
    }
}

[Export]
public class XLHandler
{
    [Import(typeof(IMyComponent))]
    public IMyComponent _component;

    public void SomeMethod()
    {
        //try to use _component but it is null
    }
}

Assembly2

public interface IMyComponent
{
    //stuff...
}

Assembly3

[Export(typeof(IMyComponent)]
public MyComponent : IMyComponent
{
    //more stuff...
}

有人知道/为什么XLHandler中的_component变量没有被MEF容器注入?

我是否需要在Assembly2中为接口导出/创建AssemblyCatalog?

2 个答案:

答案 0 :(得分:8)

导入部件时,您可以使用属性上的[Import]属性,也可以将其作为构造函数的一部分请求并使用[ImportingConstructor]属性。

使用[导入]属性导入的任何部分在类的构造函数中都不可用

因此,在您的情况下,请更改XLHandler类,如下所示:

[Export]
public class XLHandler
{
    [ImportingConstructor]
    public void SomeMethod(MyComponent component)
    {
        _component = component;
       // You can use _component, since it has already been resolved...
    }
}

答案 1 :(得分:2)

MyBootstrapper.AutoOpen中,您需要替换:

cc.ComposeParts(this);

有类似的东西:

var handler = new XLHandler();
cc.ComposeParts(handler);

或:

var handler = cc.GetExportedValue<XLHandler>();

您无法撰写MyBootstrapper的部分,因为它没有导入。 ComposeParts什么也没做。

另一种方法是向MyBootstrapper添加导入。像:

public class MyBootstrapper
{
    [Import]
    XLHandler XLHandler;

    //Automatically called by ExcelDna library, I do not instantiate this class
    public void AutoOpen()
    {
        //Leave your implementation unchanged.
    }
}

顺便说一句,MyComponent无法编译。