我正在使用Caliburn.Micro和Autofac进行应用程序。
在我的作品根目录中,我现在面临Autofac的问题: 我必须将全局使用的IEventAggregator注入我的FirstViewModel,以及第二个IEventAggregator,它必须仅由FirstViewModel及其子项使用。
我的想法是让第二个注入Owned<IEA>
,并且它可以工作,容器提供了一个不同的IEA实例。
public FirstViewModel(
IEventAggregator globalEA,
IEventAggregator localEA,
Func<IEventAggregator, SecondViewModel> secVMFactory) {}
当我必须将事件聚合器提供给SecondViewModel时会出现问题。
要创建SecondViewModel,我使用工厂方法Func<IEA, SecondVM>
。
SecondViewModel的构造函数如下:
public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}
我希望容器将第一个注入为注册的容器,第二个将是Func<IEA, SecVM>
的IEA参数。
这是我在容器中注册的功能:
builder.Register<Func<IEventAggregator, SecondViewModel>>(
c =>
(ea) =>
{
return new SecondViewModel(
c.Resolve<IEventAggregator>(),
ea);
}
);
但是当FirstViewModel
调用它时,我收到以下错误:
Autofac.dll中出现“System.ObjectDisposedException”类型的异常,但未在用户代码中处理
其他信息:此解决操作已结束。使用lambdas注册组件时,无法存储lambda的IComponentContext'c'参数。相反,要么从'c'再次解析IComponentContext,要么解析Func&lt;&gt;基于工厂从中创建后续组件。
我无法理解问题出在哪里,你能帮帮我吗,我错过了什么?
谢谢。
答案 0 :(得分:48)
您正在secVMFactory
构造函数之外调用FirstViewModel
,因此到那时处理ResolveOperation并且在您的工厂方法中c.Resolve
将抛出异常。
幸运的是,异常消息非常具有说明性,并告诉您该怎么做:
使用lambdas注册组件时,IComponentContext'c' 无法存储lambda的参数。相反,要么解决 IComponentContext再次来自'c'
因此,您无需致电c.Resolve
,而是需要解决IComponentContext
c
并在工厂中使用该功能:
builder.Register<Func<IEventAggregator, SecondViewModel>>(c => {
var context = c.Resolve<IComponentContext>();
return ea => {
return new SecondViewModel(context.Resolve<IEventAggregator>(), ea);
};
});