AM MVCアプリでUnityを使用しています。どこから始めますか?
まず、同じセッションで要求間で同じインスタンスが使用されることを保証するASP.NETシステムがないため、セッションシングルトンは実際には不可能です。セッションは、リクエスト間でシリアライズおよびデシリアライズすることで、セッション内で永続化された同じオブジェクトを模倣することができます。
一時インスタンス - つまり、生涯管理仕様のない単純な登録は、99%の時間で十分です。これは、登録された型のインスタンスが必要なたびに作成されることを意味します。
ごくまれに、要求の存続期間中存続するインスタンスが必要です。しかし、あなたがそれらを必要とするときは、本当にそれらが必要です。 DBへの接続はこれのための完全な候補です。一方、リクエストシングルトンは、作成と管理がずっと簡単です。
最も洗練された解決策は、Unityの子コンテナ機能を使用することです。リクエストの最後に配置された子コンテナをリクエストの最初に作成することができます(追加のボーナスとしてContainerControlledLifetimeManager
のインスタンスをすべて破棄します)。
子コンテナを作成する場合、親コンテナからすべての登録が引き続き使用できるため、リクエスト固有のものを子コンテナに登録する必要があります。ここで
この作業を取得するための擬似コードです:実行する必要がある
private void Application_Start() {
_parentContainer = new UnityContainer();
//creates a transient registration, available at any point in the app.
_parentContainer.RegisterType<IParentIntf, ParentIntfImpl>();
ControllerBuilder.Current.SetControllerFactory(new ServiceLocatorControllerFactory());
}
private void Application_BeginRequest() {
var childContainer = _parentContainer.CreateChildContainer();
//registers a request "singleton"
//This registration is a type registration, an instance of RequestInterfaceImpl
//will be created when needed and then kept in the container for later use.
childContainer.RegisterType<IRequestInterface,RequestInterfaceImpl>(new ContainerControlledLifetimeManager());
//save the child container in the context, so we can use it later
HttpContext.Items["childContainer"] = childContainer;
}
private void Application_EndRequest() {
//dispose the child container
((IUnityContainer)HttpContext.Items["childContainer"]).Dispose();
}
もうひとつは、コントローラを作成するために、子コンテナを使用するようにコントローラの工場をオーバーライドすることです。コントローラは、アプリケーションへの最初のエントリポイントであり、コンストラクタ内の他のコンポーネントに依存することができます。
public class UnityControllerFactory : DefaultControllerFactory {
#region IControllerFactory Members
public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController controller;
controllerName = controllerName.ToLower();
var container = ((IUnityContainer)HttpContext.Items["childContainer"])
if(container.IsRegistered<IController>(controllerName))
controller = container.Resolve<IController>(controllerName);
else
controller = base.CreateController(requestContext, controllerName) ;
return controller;
}
}
「キー」に対してインスタンスを登録している場合は、Unityをキャッシュとして使用したいと思うようです。これは本当にユニティが\のベストなものではなく、あなたが得ている答えが混乱しているのかもしれません。 –
Unityをキャッシュとして使用すると、Webファームを持っているときに何が起こるのですか、ASP.Netワーカープロセスがリサイクルするときに何が起こりますか? –
@chibacityが言ったことに加えて、別のスレッド間でインスタンスを共有している場合、あなたは傷つく世界のために自分自身を開いています。特定の要求にどのスレッドが対応しているかは完全に非決定的なので、アクセスしたいときは左と中央を同期させる必要があります。本当に、新しいオブジェクトを作成する、それがDBへの旅行を必要とするならevernはそれほど高価ではありません。 –