Autofac和Func工厂 [英] Autofac and Func factories

查看:284
本文介绍了Autofac和Func工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on an application using Caliburn.Micro and Autofac.

在我的合成根目录下,我现在面临Autofac的问题: 我必须将全局使用的IEventAggregator注入到我的FirstViewModel中,然后再注入第二个IEventAggregator,该IEventAggregator只能由该FirstViewModel及其子级使用.

In my composition root I'm now facing a problem with Autofac: I have to inject the globally used IEventAggregator into my FirstViewModel, and a second IEventAggregator that has to be used only by this FirstViewModel and it's children.

我的想法是将第二个作为Owned<IEA>注入,并且它的工作原理是,容器提供了另一个IEA实例.

My idea was to make the second one be injected as Owned<IEA>, and it works, the container provides a different instance of IEA.

public FirstViewModel(
    IEventAggregator globalEA,
    IEventAggregator localEA,
    Func<IEventAggregator, SecondViewModel> secVMFactory) {}

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

The problem comes when I have to provide the event aggregators to the SecondViewModel.

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

To create the SecondViewModel I use a factory method as Func<IEA, SecondVM>. The SecondViewModel's constructor is the following:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}

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

I want the container to inject the first as the registered one, and the second will be the IEA parameter of the Func<IEA, SecVM>.

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

this is the function I registered in the container:

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

但是当它被FirstViewModel调用时,出现以下错误:

but when it gets called by the FirstViewModel I get the following error:

Autofac.dll中发生了'System.ObjectDisposedException'类型的异常,但未在用户代码中处理

An exception of type 'System.ObjectDisposedException' occurred in Autofac.dll but was not handled in user code

其他信息:此解析操作已经结束.使用Lambda注册组件时,无法存储IComponentContext'c'参数到lambda.而是从"c"再次解析IComponentContext,或从基于Func<>的工厂解析以从中创建后续组件.

Additional information: This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.

我不明白问题出在哪里,请您能帮助我,我想念什么?

I can't understand where the problem is, can you help me please, what am I missing?

谢谢.

推荐答案

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

You are calling secVMFactory outside of your FirstViewModel constructor so by that time the ResolveOperation is disposed and in your factory method the c.Resolve will throw the exception.

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

Luckily the exception message is very descriptive and telling you what to do:

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

When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c'

因此,除了调用c.Resolve之外,您还需要从c解析IComponentContext并将其用于工厂功能:

So instead of calling c.Resolve you need to resolve the IComponentContext from c and use that in your factory func:

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

这篇关于Autofac和Func工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆