哦,哇,在MVC應用程序中使用Unity的生命週期管理。我從哪說起呢?
首先,會話單例不是真的可行,因爲沒有ASP.NET系統可以保證在同一個會話中的請求之間使用同一個實例。會話可以通過在請求之間對其進行序列化和反序列化來模仿會話中保存的同一對象。
瞬態實例 - 即無需生命週期管理規範的簡單註冊在99%的時間內就足夠了。這意味着每次需要時都會創建一個註冊類型的實例。
您很少需要實例來貫穿請求的整個生命週期。但是,當你需要那些,你真的需要那些。與數據庫的連接是完美的選擇。另一方面,請求單身人士更容易創建和管理。
最優雅的解決方案是使用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最擅長的\,也可能是您收到的答案令人困惑的原因。 – 2011-01-11 19:22:24
如果你確實使用Unity作爲緩存,當你有一個Web服務器場時會發生什麼,或者當ASP.Net工作者進程再循環時會發生什麼? – 2011-01-11 19:32:31
除了@chibacity說了什麼之外,如果你在不同的線程之間共享實例,那麼你正打開一個讓自己受到傷害的世界。哪個線程爲特定的請求提供服務是完全不確定的,並且當您想要訪問它時,您需要同步左側和右側中心。真的,創造新的對象,如果它需要去數據庫旅行並不昂貴。 – 2011-01-11 22:41:54