ASP.NET MVC: il controller è stato creato per ogni richiesta?

Domanda molto semplice: i controller in ASP.NET vengono creati per ogni richiesta HTTP oppure vengono creati all’avvio dell’applicazione e riutilizzati in tutte le richieste?

Il controller verrà creato solo per una particolare richiesta HTTP?

Se le mie supposizioni precedenti sono corrette, posso dipendere da questo? Voglio creare un contesto di database (Entity Framework) che vivrà solo per una richiesta. Se lo creo come proprietà inizializzata nel costruttore del controllore, è concesso che su ogni richiesta venga creata una nuova istanza di contesto?

Un Controller viene creato per ogni richiesta da ControllerFactory (che di default è DefaultControllerFactory).

http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx

Si noti che Html Helper Html.Action creerà un altro controller.

La versione breve è che ControllerActivator.Create viene chiamato (per ogni richiesta) per creare un controller (che si trova in un nuovo controller tramite DependencyResolver o tramite Activator se non è stato impostato alcun resolver):

 public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType)); } 

La versione più lunga è questa (ecco il codice dalla sorgente From the 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)); } } 

Ecco il codice di fabbrica del controller

  public virtual IController CreateController(RequestContext requestContext, string controllerName) { Type controllerType = GetControllerType(requestContext, controllerName); IController controller = GetControllerInstance(requestContext, controllerType); return controller; } 

Il che praticamente lo chiama:

 protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return ControllerActivator.Create(requestContext, controllerType); } 

Che chiama questo metodo in ControllerActivator (questo codice prova a chiedere DependencyResolver per un’istanza o semplicemente usa la class Activator):

 public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType)); } 

Questo potrebbe rientrare in troppe informazioni … Ma volevo dimostrare di avere davvero un nuovo controller per OGNI richiesta.

Ho creato un costruttore vuoto per un controller e ho inserito un punto di interruzione nel costruttore. Ha colpito ogni volta che c’era una nuova richiesta. Quindi penso che sia stato creato per ogni richiesta.

Il controller verrà creato quando viene eseguita qualsiasi azione in un controller specifico.

Ho un progetto in cui tutti i miei controller ereditano da un ApplicationController e ogni volta che viene eseguita un’azione, il punto di interruzione viene colpito all’interno di ApplicationController , indipendentemente dal suo controller ” corrente “.

Inizializzo il mio agente (che funziona come mio contesto) ogni volta che il mio controller viene creato come tale:

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

Questo ovviamente non è quello che ti serve – come hai detto che volevi una singola istanza ogni volta che veniva chiamata. Ma è un buon posto per verificare cosa sta succedendo ogni volta e per garantire che al momento non esista un’altra istanza del tuo contesto.

Spero che questo ti aiuti.

I controller sono creati per ogni richiesta. La magia avviene nel routing nel gobal.aspx. I percorsi di mapping indirizzano MVC a quale controller creare e l’azione sul controller da chiamare e i parametri da passare ad essi.

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