Autofac和Func工厂

Ser*_*gio 25 .net dependency-injection mvvm autofac caliburn.micro

我正在使用Caliburn.Micro和Autofac开发应用程序.

在我的组合根目录中,我现在面临着Autofac的问题:我必须将全局使用的IEventAggregator注入我的FirstViewModel,以及第二个IEventAggregator,它必须仅由FirstViewModel及其子项使用.

我的想法是将第二个注入Owned<IEA>,并且它起作用,容器提供了IEA的不同实例.

public FirstViewModel(
    IEventAggregator globalEA,
    IEventAggregator localEA,
    Func<IEventAggregator, SecondViewModel> secVMFactory) {}
Run Code Online (Sandbox Code Playgroud)

当我必须向SecondViewModel提供事件聚合器时,问题就出现了.

要创建SecondViewModel,我使用工厂方法Func<IEA, SecondVM>.SecondViewModel的构造函数如下:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}

我希望容器注入第一个作为注册的容器,第二个将是IEA参数Func<IEA, SecVM>.

这是我在容器中注册的功能:

builder.Register<Func<IEventAggregator, SecondViewModel>>(
     c =>
         (ea) =>
         {
             return new SecondViewModel(
                 c.Resolve<IEventAggregator>(),
                 ea);
         }
);
Run Code Online (Sandbox Code Playgroud)

但当它被FirstViewModel我调用时,我得到以下错误:

Autofac.dll中出现"System.ObjectDisposedException"类型的异常,但未在用户代码中处理

附加信息:此解析操作已结束.使用lambdas注册组件时,无法存储lambda的IComponentContext'c'参数.相反,要么从'c'再次解析IComponentContext,要么解析基于Func <>的工厂以从中创建后续组件.

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

谢谢.

nem*_*esv 53

您正在构造函数secVMFactory之外调用,FirstViewModel因此到那时处理ResolveOperation并且在您的工厂方法c.Resolve中将抛出异常.

幸运的是,异常消息非常具有描述性,并告诉您该怎么做:

使用lambdas注册组件时,无法存储lambda的IComponentContext'c'参数.相反,要么从'c'再次解析IComponentContext

因此,而不是调用c.Resolve你需要解析IComponentContextfrom c并在你的工厂func中使用它:

builder.Register<Func<IEventAggregator, SecondViewModel>>(c => {
     var context = c.Resolve<IComponentContext>();
     return ea => { 
          return new SecondViewModel(context.Resolve<IEventAggregator>(), ea); 
     };
});
Run Code Online (Sandbox Code Playgroud)