非常簡單的問題:ASP.NET中的控制器是否爲每個HTTP請求創建,還是應用程序啓動時創建並在整個請求中重用?ASP.NET MVC:控制器是否爲每個請求創建?
是否僅爲特定的HTTP請求創建控制器?
如果我以前的假設是正確的,我可以依靠它嗎?我想創建僅適用於一個請求的數據庫上下文(實體框架)。如果我將它創建爲在控制器構造函數中初始化的屬性,那麼它是否被授予爲每個請求創建新的上下文實例?
非常簡單的問題:ASP.NET中的控制器是否爲每個HTTP請求創建,還是應用程序啓動時創建並在整個請求中重用?ASP.NET MVC:控制器是否爲每個請求創建?
是否僅爲特定的HTTP請求創建控制器?
如果我以前的假設是正確的,我可以依靠它嗎?我想創建僅適用於一個請求的數據庫上下文(實體框架)。如果我將它創建爲在控制器構造函數中初始化的屬性,那麼它是否被授予爲每個請求創建新的上下文實例?
控制器被用於通過的ControllerFactory(默認情況下是DefaultControllerFactory)每個請求創建。
http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx
注意,Html.Action
HTML輔助將創造另一個控制器。
短的版本是,ControllerActivator.Create
被稱爲(爲每個請求)來創建一個控制器(通過DependencyResolver或通過激活,如果沒有解決程序已經設置了哪些inits一個新的控制器):
public IController Create(RequestContext requestContext, Type controllerType) {
try {
return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
}
較長版本是這樣(這裏是從源代碼從MvcHandler)
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
SecurityUtil.ProcessInApplicationTrust(() =>
{
IController controller;
IControllerFactory factory;
ProcessRequestInit(httpContext, out controller, out factory);
try
{
controller.Execute(RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
});
}
private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
//non relevant code
// Instantiate the controller and call Execute
factory = ControllerBuilder.GetControllerFactory();
controller = factory.CreateController(RequestContext, controllerName);
if (controller == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.ControllerBuilder_FactoryReturnedNull,
factory.GetType(),
controllerName));
}
}
這裏的控制器工廠代碼
public virtual IController CreateController(RequestContext requestContext, string controllerName) {
Type controllerType = GetControllerType(requestContext, controllerName);
IController controller = GetControllerInstance(requestContext, controllerType);
return controller;
}
這基本上要求是:
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
return ControllerActivator.Create(requestContext, controllerType);
}
其中要求在ControllerActivator此方法(此代碼試圖詢問DependencyResolver一個實例,或者只是使用Activator類):
public IController Create(RequestContext requestContext, Type controllerType) {
try {
return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
}
這可能屬於太多的信息......但我想表明,你真的得到一個新的控制器爲每個請求。
我爲控制器創建了一個空構造函數,並在構造函數中放置了一個斷點。每次有新的請求時它都會被擊中。所以我認爲它是爲每個請求創建的。
+1我希望你是對的,但我希望獲得一些更好的認可知識,而不僅僅是「在我試過它的所有情況下」。如果由於某種原因它有時不能這樣工作,那就意味着一個錯誤。 – drasto 2011-03-24 21:58:07
@drasto:不用擔心。控制器爲每個請求實例化。有些內存雖然得到了重用,但你不應該擔心控制器的狀態(如果你有的話)。它將按預期進行初始化。 **但是**可能會出現多個控制器將被實例化的情況。這就是當視圖調用控制器動作(即''Html.RenderAction(「action」,「controller」);') – 2011-03-24 23:24:58
@RobertKoritnik&Bala R,我有一個問題請。在操作方法將它們或它們提供給視圖後,像Student或List
控制器將在執行特定控制器中的任何操作時創建。
我有一個執行的動作,每次一個項目,我所有的控制器從ApplicationController
繼承,斷點打ApplicationController
內 - 無論其「當前」控制器。
我初始化我的經紀人(用作我的上下文)每當創建我的控制器就像這樣:
public IWidgetAgent widgetAgent { get; set; }
public WidgetController()
{
if (widgetAgent == null)
{
widgetAgent = new WidgetAgent();
}
}
這顯然不是你所需要的 - 因爲你提到你每次只需要1個實例它被稱爲。但是這是一個很好的地方,可以檢查每次發生的情況,並確保您的上下文的另一個實例當前不存在。
希望這會有所幫助。
爲每個請求創建控制器。神奇的發生在gobal.aspx的路由中。映射路徑指示MVC控制器創建並在控制器上調用的動作以及傳遞給它們的參數。
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb
在你的構造函數中放置一個斷點,看看你能找到什麼... – 2011-03-24 21:50:35
@Greg B:除了它不會告訴我它是否總是這樣的行爲 - 如果情況改變,某些控制器會改變它的行爲I有錯誤,可能真的很難找到... – drasto 2011-03-24 21:54:04
@drasto你將如何檢查它是否總是這樣工作?檢查您的應用程序的每個請求? – 2011-03-24 21:56:50