Pregunta ASP.NET MVC: ¿Se creó el controlador para cada solicitud?


Pregunta muy simple: ¿Los controladores en ASP.NET se crean para cada solicitud HTTP, o se crean al inicio de la aplicación y se reutilizan en todas las solicitudes?

¿Se creará el controlador solo para una solicitud HTTP particular?

Si mis suposiciones anteriores son correctas, ¿puedo confiar en eso? Quiero crear un contexto de base de datos (Entity Framework) que viva solo para una solicitud. Si lo creo como una propiedad inicializada en el constructor del controlador, ¿se concede que se creará una nueva instancia de contexto para cada solicitud?


74
2018-03-24 21:41


origen


Respuestas:


Se crea un controlador para cada solicitud de ControllerFactory (que de forma predeterminada es DefaultControllerFactory).

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

Tenga en cuenta que Html.Action Html Helper creará otro controlador.

La versión corta es que ControllerActivator.Create se llama (para cada solicitud) para crear un Controlador (que se inserta en un Controlador nuevo a través de DependencyResolver o mediante el Activador si no se ha configurado un Resolver):

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

La versión más larga es esta (Aquí está el código de la fuente 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));
            }
        }

Aquí está el código de fábrica del controlador

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

Lo que básicamente se llama esto:

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

Lo cual llama a este método en el ControllerActivator (Este código intenta pedirle a DependencyResolver una instancia, o simplemente usa la clase Activator):

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

Esto podría caer en Demasiada información ... Pero quería mostrar que realmente OBTIENE un nuevo controlador para CADA solicitud.


75
2018-03-24 22:00



Creé un constructor vacío para un controlador y puse un punto de ruptura en el constructor. Recibió un golpe cada vez que hubo una nueva solicitud. Así que creo que está creado para cada solicitud.


25
2018-03-24 21:52



El controlador se creará cuando se realice cualquier acción en un controlador específico.

Tengo un proyecto donde todos mis controladores heredan de un ApplicationController y cada vez que se realiza una acción, se golpea el punto de interrupción dentro del ApplicationController - independientemente de su "corriente" Controlador.

Inicializo mi agente (que funciona como mi contexto) cada vez que mi controlador se crea así:

    public IWidgetAgent widgetAgent { get; set; }

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

    }

Evidentemente, esto no es lo que necesita, ya que mencionó que solo quería una sola instancia cada vez que se llamaba. Pero es un buen lugar para verificar lo que está sucediendo cada vez y para asegurarse de que no exista otra instancia de su contexto actualmente.

Espero que esto ayude.


2
2018-03-24 21:55



Los controladores se crean para cada solicitud. La magia ocurre en el enrutamiento en gobal.aspx. Las rutas de mapeo dirigen MVC a qué controlador crear y actuar en el controlador para llamar, y los parámetros que se les pasan.

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


1
2018-03-24 21:57