2011-03-24 88 views
67

非常簡單的問題:ASP.NET中的控制器是否爲每個HTTP請求創建,還是應用程序啓動時創建並在整個請求中重用?ASP.NET MVC:控制器是否爲每個請求創建?

是否僅爲特定的HTTP請求創建控制器?

如果我以前的假設是正確的,我可以依靠它嗎?我想創建僅適用於一個請求的數據庫上下文(實體框架)。如果我將它創建爲在控制器構造函數中初始化的屬性,那麼它是否被授予爲每個請求創建新的上下文實例?

+11

在你的構造函數中放置一個斷點,看看你能找到什麼... – 2011-03-24 21:50:35

+3

@Greg B:除了它不會告訴我它是否總是這樣的行爲 - 如果情況改變,某些控制器會改變它的行爲I有錯誤,可能真的很難找到... – drasto 2011-03-24 21:54:04

+0

@drasto你將如何檢查它是否總是這樣工作?檢查您的應用程序的每個請求? – 2011-03-24 21:56:50

回答

73

控制器被用於通過的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

{{citation needed} } – 2011-03-24 22:02:57

+0

確實需要。我找不到任何此類信息... – drasto 2011-03-24 22:07:37

+1

http://msdn.microsoft.com/en-us/library/dd381612.aspx – BlackICE 2011-03-24 22:21:06

24

我爲控制器創建了一個空構造函數,並在構造函數中放置了一個斷點。每次有新的請求時它都會被擊中。所以我認爲它是爲每個請求創建的。

+2

+1我希望你是對的,但我希望獲得一些更好的認可知識,而不僅僅是「在我試過它的所有情況下」。如果由於某種原因它有時不能這樣工作,那就意味着一個錯誤。 – drasto 2011-03-24 21:58:07

+6

@drasto:不用擔心。控制器爲每個請求實例化。有些內存雖然得到了重用,但你不應該擔心控制器的狀態(如果你有的話)。它將按預期進行初始化。 **但是**可能會出現多個控制器將被實例化的情況。這就是當視圖調用控制器動作(即''Html.RenderAction(「action」,「controller」);') – 2011-03-24 23:24:58

+0

@RobertKoritnik&Bala R,我有一個問題請。在操作方法將它們或它們提供給視圖後,像Student或List 這樣創建的對象會發生什麼情況?他們是否被處置?當新請求出現時,這些對象會發生什麼? – 2017-08-07 08:03:18

2

控制器將在執行特定控制器中的任何操作時創建。

我有一個執行的動作,每次一個項目,我所有的控制器從ApplicationController繼承,斷點打ApplicationController內 - 無論其「當前」控制器。

我初始化我的經紀人(用作我的上下文)每當創建我的控制器就像這樣:

public IWidgetAgent widgetAgent { get; set; } 

    public WidgetController() 
    { 
     if (widgetAgent == null) 
     { 
      widgetAgent = new WidgetAgent(); 
     } 

    } 

這顯然不是你所需要的 - 因爲你提到你每次只需要1個實例它被稱爲。但是這是一個很好的地方,可以檢查每次發生的情況,並確保您的上下文的另一個實例當前不存在。

希望這會有所幫助。

1

爲每個請求創建控制器。神奇的發生在gobal.aspx的路由中。映射路徑指示MVC控制器創建並在控制器上調用的動作以及傳遞給它們的參數。

http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb

+0

*需要引用* - 在鏈接的文檔中找不到支持信息。謝謝 – drasto 2011-03-24 22:09:31

+1

http://stackoverflow.com/questions/1763775/asp-net-mvc-controller-lifecycle – BlackICE 2011-03-24 22:22:12

+1

http://msdn.microsoft.com/en-us/library/dd381612.aspx – BlackICE 2011-03-24 22:22:38

相關問題