【问题标题】:MEF Import is nullMEF 导入为空
【发布时间】:2013-03-02 22:44:31
【问题描述】:

我有一个不起作用的导入 - 对象为空。最初它是 ImportMany,但我将其简化为 Import 以尝试识别问题,但我没有成功。

我浏览了这个网站和谷歌并遵循了主要想法:

  • 不要自己实例化类,让 MEF 来做,否则调用 container.getExport() - 仍然不起作用
  • 在包含 [Import] 属性的类上放置 [Export],否则容器组合过程不会将其作为一部分拾取(在调试时确认)。

我的代码设置如下(为简洁起见进行了简化):

组装1

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 吗?

【问题讨论】:

  • 对此不是 100% 确定,但 import 属性不应该是 [Import(typeof(IMycomponent))]
  • 是的,您导出为IMyComponent,因此您也必须以此方式导入。您可以从导入中删除 typeof 定义,因为您的变量类型已经是 IMyComponent。
  • 是的,这是 Q 中的一个错字。我会改正的。

标签: c# dependency-injection null mef


【解决方案1】:

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

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

所以在你的情况下,像这样改变XLHandlerclass:

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

【讨论】:

  • 那么 [Import] 的意义何在 - 对不起,我没能理解它。如何直接注入属性/类变量?
  • [Import] 可以在您不需要在构造函数中立即解析该部分时使用。它会在构造函数完成之后和您调用该实例的任何属性/方法之间的一段时间后解决。
  • 好的,所以我已将类变量更改为属性(添加 {get;set;})但它仍然为空。理想情况下,我不想将变量作为方法参数传递,所以仍然对为什么 [Import] 不注入属性感到困惑。
  • 如果你试图在构造函数中引用它,它仍然是空的......如果你想要它在构造函数中(或从构造函数内部调用的任何方法),你需要将其作为参数传递给构造函数并使用[ImportingConstructor]
  • 嗯,好的。我不是在构造函数中提到它——我还没有定义一个。我猜是因为 ExcelDNA 库正在实例化该类,它可能在 MEF 可以运行 [Import] 之前这样做?
【解决方案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 无法编译。

【讨论】:

  • 干杯。我实际上使用了两个答案的组合,但不确定如何同时接受这两个答案。两者都通过了。
  • @Murtuza 没问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
相关资源
最近更新 更多