Autofac和Func工厂

时间:2013-12-14 12:33:08

标签: .net mvvm dependency-injection autofac caliburn.micro

我正在使用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;基于工厂从中创建后续组件。

我无法理解问题出在哪里,你能帮帮我吗,我错过了什么?

谢谢。

1 个答案:

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