Simple InjectorをIoCコンテナーとして使用しており、次の手法を使用して、Webリクエストごとまたはスレッドごとの両方で一部のオブジェクトの「混合」ライフスタイルを登録できるようにしています。
interface IUnitOfWork { }
interface IWebUnitOfWork : IUnitOfWork { }
interface IThreadUnitOfWork : IUnitOfWork { }
class UnitOfWork : IWebUnitOfWork, IThreadUnitOfWork { }
container.RegisterPerWebRequest<IWebUnitOfWork, UnitOfWork>();
container.RegisterLifetimeScope<IThreadUnitOfWork, UnitOfWork>();
container.Register<IUnitOfWork>(() => container.GetInstance<UnitOfWork>());
// Register as hybrid PerWebRequest / PerLifetimeScope.
container.Register<UnitOfWork>(() =>
{
if (HttpContext.Current != null)
return container.GetInstance<IWebUnitOfWork>() as UnitOfWork;
else
return container.GetInstance<IThreadUnitOfWork>() as UnitOfWork;
});
私はこのソリューションに完全に満足しているわけではありません。各要件について、それを機能させるために追加の空のインターフェイスを定義し、それらが私の具象クラスによって参照されるようにする必要があります。
追加のインターフェイスを定義する代わりに、次の拡張メソッドを使用しない理由はありますか?これらのメソッドに問題がある場合、コンテナーの現在のインスタンスがIIS内で実行されていることを完全に確信して確立する他の方法はありますか?
public static void RegisterHybridLifestyle<TService, TImplementation>(
this Container container)
where TService : class
where TImplementation : class, TService
{
if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
container.RegisterPerWebRequest<TService, TImplementation>();
else
container.RegisterLifetimeScope<TService, TImplementation>();
}
public static void RegisterForLifestyle<TConcrete>(
this Container container)
where TConcrete : class
{
if (HostingEnvironment.ApplicationHost != null)
container.RegisterPerWebRequest<TConcrete>();
else
container.RegisterLifetimeScope<TConcrete>();
}
アップデート
上記の質問とそれに続く質問は、SimpleInjectorとハイブリッド登録の誤解に基づいていました。上記およびSOの他の場所で説明されている手法は、コンテナーがWeb要求とWeb要求のコンテキスト内で実行されていないバックグラウンドプロセスの両方の要求を処理できる場合に使用されます。私が達成しようとしているのは、Webリクエストとスレッドリクエストの両方に適したコンテナの構成に対応するための変数登録です。つまり、IIS内で機能し、Windowsサービス内で機能するようにコンテナーを構成する必要があります。両方に同時に対応できる動的登録は必要ありません。
この結果は次の拡張メソッドであり、ソリューションから「余分な」インターフェイスを削除しました:-)
public static void RegisterForScope<TService, TImplementation>(this Container container)
where TService : class
where TImplementation : class, TService
{
if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
container.RegisterPerWebRequest<TService, TImplementation>();
else
container.RegisterLifetimeScope<TService, TImplementation>();
}
public static void RegisterForScope<TConcrete>(this Container container)
where TConcrete : class
{
if (System.Web.Hosting.HostingEnvironment.ApplicationHost != null)
container.RegisterPerWebRequest<TConcrete>();
else
container.RegisterLifetimeScope<TConcrete>();
}