Autofac 和 Func 工厂

Posted

技术标签:

【中文标题】Autofac 和 Func 工厂【英文标题】:Autofac and Func factories 【发布时间】:2014-01-02 05:10:37 【问题描述】:

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

在我的作文根目录中,我现在遇到了 Autofac 的问题: 我必须将全局使用的 IEventAggregator 注入到我的 FirstViewModel 中,以及必须仅由该 FirstViewModel 及其子级使用的第二个 IEventAggregator。

我的想法是让第二个注入为Owned<IEA>,它可以工作,容器提供了一个不同的 IEA 实例。

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

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

要创建 SecondViewModel,我使用工厂方法 Func&lt;IEA, SecondVM&gt;。 SecondViewModel 的构造函数如下:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA)

我希望容器注入第一个作为注册的,第二个将是Func&lt;IEA, SecVM&gt;的IEA参数。

这是我在容器中注册的函数:

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

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

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

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

我不明白问题出在哪里,请你帮帮我,我错过了什么?

谢谢。

【问题讨论】:

【参考方案1】:

您在FirstViewModel 构造函数之外调用secVMFactory,所以到那时ResolveOperation 已被释放,在您的工厂方法中c.Resolve 将抛出异常。

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

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

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

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

【讨论】:

哈哈我试过这样做,但我把它放在内部函数中,所以我一直收到同样的错误! +1 还有一个问题:我应该在每次注册时都这样做以防止任何 vm 订单实例化重构吗? 这取决于您的要求,当您将Func 注册到容器中时,您始终可以c.Resolve&lt;IComponentContext&gt;();,或者仅在您实际需要在您的容器中调用Resolve 的情况下才这样做工厂。 你可以在The Curious Case of a Deadlock in Autofac的帖子中阅读更多关于这个问题的信息 感谢您的出色回答,它解决了我的问题!我只是不完全理解解决方案。如果 c 在我们使用注册的 Func 时超出了范围,那么 context 怎么没有超出范围呢?谢谢!

以上是关于Autofac 和 Func 工厂的主要内容,如果未能解决你的问题,请参考以下文章

期货大赛项目|三,autofac简单用法

[Asp.Net Core]Autofac整合.NET5 MVC

[Asp.Net Core]Autofac整合.NET5 MVC

用Autofac替换.net core 内置容器

用Autofac替换.net core 内置容器

根据运行时会话值从 Autofac 解析服务实现