web-dev-qa-db-ja.com

リクエストの終わりまでにリソースを解放し、注入されたサービスをASP.NET 5 / Coreで破棄する方法は?

ASP.NET CoreのデフォルトのDependency Injection Containerを使用してコントローラーに注入されるサービスがあります。

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

services.AddScoped<FooBarService>();

これにより、リクエストごとに1つのインスタンスが作成されます。フレームワークがデストラクタやガベージコレクションに依存せずに、各リクエストの終わりまでにFooBarServiceインスタンスを確実に破棄する方法を教えてください。

20
x2bool

他のすべてのDIコンテナと同様に、インスタンスの寿命を考慮してIDisposableインスタンスを破棄します。

あなたの状況では、インスタンスがScoped(リクエストごとのインスタンス)として登録されている場合。リクエストが完了すると、このインスタンスを破棄します。

編集:公式文書では彼らはこれについて言及していません。ソースコードを確認してみましょう:

スコープが作成されると、 ServiceScopeFactory は新しい ServiceScope を返します。これは ServiceProvider に依存し、使い捨てです。

ServiceProviderには_private List<IDisposable> _transientDisposables;_があり、TransientCallSiteinvokedのCaptureDisposableメソッドであるときに使い捨てサービスを保持します。また、ServiceProviderにはScopedのすべてのサービスを保持するprivate readonly Dictionary<IService, object> _resolvedServices = new Dictionary<IService, object>();があります。

Liftime/scopeが終了すると、ServiceScopeは破棄されます。次に、すべての__transientDisposables_を破棄するServiceProviderを破棄し、次に__resolvedServices_をチェックして、ServiceProviderのディクショナリ内の破棄可能なサービスを破棄します。

編集(13.06.2017):彼らは現在公式文書で言及しています。 サービスの破棄

27
Erkan Demirel

AddScopedを使用する場合は 設計による であり、オブジェクトはそのライフタイムをリクエストに関連付けます。

7
Matias Quaranta

まだ誰もこれについて言及していませんが、IDisposableを型に実装する以外に、{HttpContext}.Response.RegisterForDispose(objectToDispose)を使用することもできます。通常、これは、リクエストが終了したときに破棄されるリクエスト(コントローラーアクションなど)の開始時にオブジェクトを登録するために使用されます。

2
James Wilkins