我有一个无效的导入 - 该对象为null。最初它是一个ImportMany,但我将其简化为导入以尝试识别问题,但我没有成功这样做。
我已经浏览了这个网站和Google,并遵循了主要想法:
我的代码设置如下(为了紧凑而简化):
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?
答案 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
无法编译。