ServiceStack の使用 自己ホスト Web アプリケーションでのオブジェクトの有効期間管理の問題に行き詰まりました。
私の要件:
- リクエストごとのオブジェクトのライフタイム スコープの必要性。
- ServiceStack IoC アダプターを実装した Castle Windsor IoC を使用しています。
- 私のアプリケーションは、基本クラス AppHostHttpListenerPoolBase (ServiceStack v4) で自己ホストされています
- おそらくいつの日か IIS に移行したいと考えているので、IIS は柔軟でなければなりません。
一般的な問題:
Castle Windsor IoC は、独自の要求ごとの有効期間戦略を実装していますが、http モジュールにバインドされているため、IIS でホストされているアプリでのみ機能します。したがって、オブジェクトの有効期間を処理するために、カスタム IScopeAccessor (Castle Windsor によって提供される) を実装する必要があります。ここでの問題は、現在のリクエストにバインドするために使用できるフックがないことです。
与えられた
public class MyScopeAccessor : IScopeAccessor
{
public ILifetimeScope GetScope(CreationContext context)
{
//implement it
}
}
GetScope メソッドを実装する必要があります。
私が完了できない主なアイデアが 2 つあります。
[Threadstatic] の使用
MyScopeAccessor に保存するだけです
[ThreadStatic]
private static ILifetimeScope _currentLifetimeScope;
まだ初期化されていない場合は、最初の GetScope の後に新しいスコープを作成します。
問題:
- 処分しにくい。_currentLifetimeScope を破棄する最善の方法は、AfterEachRequest メソッドをオーバーライドするカスタム IServiceRunner を実装する (または ServiceRunner から継承する) ことです。しかし、AfterEachRequest が実際にリクエスト スレッドで実行されるかどうかは正確にはわかりません。
- IIS に移行すると、いくつかの問題が発生する可能性があります。なぜなら、IIS は広告と要求コンテキストの間の変更不可能なバインディングを保証していないからです。
IRequest インスタンスの使用
MyScopeAccessor に保存するだけです
private static readonly ConcurrentDictionary<IRequest, ILifetimeScope> LifetimeScopes;
対応するカスタム ServiceRunner メソッド (OnBeforeEachRequest、OnAfterEachRequest) で現在の有効期間スコープを作成して破棄します。
問題:
- GetScope から現在のリクエストにグローバルにアクセスする方法がわかりません。MyScopeAccessor は、サービスとリクエストについて何も知りません。
また、ServiceStack のデフォルトの Funq IoC がこの問題を解決するかどうかも興味深いです。