Как освободить ресурсы и избавиться от внедренной службы в ASP.NET 5/Core к концу запроса?

У меня есть служба, которая вводится в контроллер с использованием контейнера для инъекций зависимостей по умолчанию ASP.NET Core:

public class FooBarService : IDisposable {
    public void Dispose() { ... }
}

services.AddScoped<FooBarService>();

Это создает один экземпляр для запроса. Как обеспечить, чтобы инфраструктура удаляла экземпляр FooBarService до конца каждого запроса, не полагаясь на деструкторы и сбор мусора?

Ответы

Ответ 1

Как и все другие контейнеры DI, он будет располагать экземпляры IDisposable для вас с учетом времени жизни экземпляра.

В вашем заявлении, если экземпляр зарегистрирован как Scoped (экземпляр на запрос). Он будет удалять этот экземпляр после завершения запроса.

Edit: В официальных документах они не упоминают об этом. Итак, проверьте исходный код:

Когда создается область, ServiceScopeFactory возвращает новый ServiceScope, который зависит от ServiceProvider и одноразового использования.

ServiceProvider имеет private List<IDisposable> _transientDisposables;, который сохраняет одноразовые службы, когда TransientCallSite равен invoke d в CaptureDisposable. Кроме того, ServiceProvider имеет private readonly Dictionary<IService, object> _resolvedServices = new Dictionary<IService, object>();, который сохраняет все службы для Scoped.

Когда лифтинг/область заканчивается, расположен ServiceScope. Затем он располагает ServiceProvider, который размещает все _transientDisposables, а затем проверяет _resolvedServices и удаляет одноразовые службы в словаре в ServiceProvider.

Изменить (13.06.2017): Сейчас они упоминаются в официальных документах. Утилизация сервисов

Ответ 2

При использовании AddScoped по дизайну, объект будет иметь время жизни, связанное с запросом.

Ответ 3

Я вижу, что никто этого не упоминал, но помимо реализации IDisposable в вашем типе, вы также можете использовать {HttpContext}.Response.RegisterForDispose(objectToDispose). Обычно это используется для регистрации объекта в начале запроса (например, действия контроллера), который должен быть удален после завершения запроса.