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

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

问题描述

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

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

在我的作文根目录中,我现在面临 Autofac 的问题:我必须将全局使用的 IEventAggregator 注入到我的 FirstViewModel 中,并将第二个 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 实例.

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.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参数.

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 注册组件时,无法存储 lambda 的 IComponentContext 'c' 参数.相反,要么从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:

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

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

因此,您需要从 c 解析 IComponentContext 并在您的工厂函数中使用它,而不是调用 c.Resolve:

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天全站免登陆