【问题标题】:Injecting a factory Func with ASP.NET Core DI使用 ASP.NET Core DI 注入工厂 Func
【发布时间】:2017-07-03 16:53:28
【问题描述】:

我正在尝试让这样的东西工作:

public class FooService : IFooService {
    public FooService(Func<IBarService> barFactory) { ... }
}
public class BarService : IBarService, IDisposable { ... }

services.AddSingleton<IFooService, FooService>();
services.AddTransient<IBarService, BarService>();
services.AddSingleton<Func<IBarService>>(ctx => () => ctx.GetService<IBarService());

这可以解决BarService 实例,但我不知道如何正确管理它的生命周期。当我在FooService 的成员之一内部执行此操作时:

using (var bar = _barFactory())
{
    ...
}

我收到ObjectDispoedException

System.ObjectDisposedException:无法访问已处置的对象。此错误的一个常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文上调用 Dispose() 或将上下文包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。

但是,如果我只执行var bar = _barFactory();,而没有 using 语句,我将无法向 DI 容器发出我已完成实例的信号,并且可以将其释放。

这里的正确方法是什么?


(旁注:是的,我知道有些人会反对单例服务不应该依赖于临时服务。这不是这里发生的事情;单例服务依赖于单例工厂 ,这会产生瞬态实例。单例然后将瞬态服务用于一两个语句,然后用它完成,所以这里应该没有实际的生命周期问题。)

【问题讨论】:

    标签: c# dependency-injection .net-core


    【解决方案1】:

    documentation中所述:

    容器将为它创建的IDisposable 类型调用Dispose。但是,如果您自己将实例添加到容器中,它不会被释放。

    所以不要使用using 语句,一切都应该没问题。

    【讨论】:

    • 但是什么时候会调用Dispose?它怎么知道我已经完成了实例?
    • @TomasLycken 容器有List&lt;IDisposable&gt;,它在作用域的末尾处理TransientScoped 对象(默认的ASP.NET Core 作用域是Web 请求)。 stackoverflow.com/a/40845639/5112433
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2017-12-23
    • 2018-07-22
    • 1970-01-01
    • 2016-07-12
    • 2012-03-21
    • 2019-06-05
    相关资源
    最近更新 更多