何时处置 .NET Core 依赖项注入实例? [英] When are .NET Core dependency injected instances disposed?

查看:35
本文介绍了何时处置 .NET Core 依赖项注入实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ASP.NET Core 使用 IServiceCollection 上的扩展方法来设置依赖注入,然后在需要类型时使用适当的方法创建新实例:

ASP.NET Core uses extension methods on IServiceCollection to set up dependency injection, then when a type is needed it uses the appropriate method to create a new instance:

  • AddTransient<T> - 添加一个每次请求都会重新创建的类型.
  • AddScoped - 添加为请求范围保留的类型.
  • AddSingleton - 在第一次请求时添加一个类型并保留它.
  • AddTransient<T> - adds a type that is created again each time it's requested.
  • AddScoped<T> - adds a type that is kept for the scope of the request.
  • AddSingleton<T> - adds a type when it's first requested and keeps hold of it.

我有实现 IDisposable 的类型,如果不处理它们会导致问题 - 在每种模式中 Dispose 实际何时被调用?

I have types that implement IDisposable and that will cause problems if they aren't disposed - in each of those patterns when is Dispose actually called?

是否需要添加任何内容(例如异常处理)以确保始终释放该实例?

Is there anything I need to add (such as exception handling) to ensure that the instance is always disposed?

推荐答案

解析的对象与其容器具有相同的生命周期/处理周期,除非您使用 using 语句或 .Dispose() 方法.

The resolved objects have the same life-time/dispose cycle as their container, that's unless you manually dispose the transient services in code using using statement or .Dispose() method.

在 ASP.NET Core 中,您会获得一个作用域容器,该容器针对每个请求进行实例化,并在请求结束时进行处理.此时,此容器创建的作用域和瞬态依赖项也将被释放(如果它们实现了 IDisposable 接口),您也可以在源代码中看到 这里.

In ASP.NET Core you get a scoped container that's instantiated per request and gets disposed at the end of the request. At this time, scoped and transient dependencies that were created by this container will get disposed too (that's if they implement IDisposable interface), which you can also see on the source code here.

public void Dispose()
{
    lock (ResolvedServices)
    {
        if (_disposeCalled)
        {
            return;
        }
        _disposeCalled = true;
        if (_transientDisposables != null)
        {
            foreach (var disposable in _transientDisposables)
            {
                disposable.Dispose();
            }

            _transientDisposables.Clear();
        }

        // PERF: We've enumerating the dictionary so that we don't allocate to enumerate.
        // .Values allocates a ValueCollection on the heap, enumerating the dictionary allocates
        // a struct enumerator
        foreach (var entry in ResolvedServices)
        {
            (entry.Value as IDisposable)?.Dispose();
        }

        ResolvedServices.Clear();
    }
}

单例在父容器被释放时被释放,通常意味着应用程序关闭时.

Singletons get disposed when the parent container gets disposed, usually means when the application shuts down.

TL;DR:只要您在应用程序启动期间不实例化范围/瞬态服务(使用 app.ApplicationServices.GetService())并且您的服务正确实现了 Disposable 接口(例如 指向MSDN)您无需处理任何事情.

TL;DR: As long as you don't instantiate scoped/transient services during application startup (using app.ApplicationServices.GetService<T>()) and your services correctly implement Disposable interface (like pointed in MSDN) there is nothing you need to take care of.

父容器在 Configure(IApplicationBuilder app) 方法之外是不可用的,除非你做了一些奇怪的事情来让它在外面访问(你不应该这样做).

The parent container is unavailable outside of Configure(IApplicationBuilder app) method unless you do some funky things to make it accessible outside (which you shouldn't anyways).

当然,我们鼓励尽快释放临时服务,尤其是在它们消耗大量资源的情况下.

Of course, its encouraged to free up transient services as soon as possible, especially if they consume much resources.

这篇关于何时处置 .NET Core 依赖项注入实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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