Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Is Controller created for every request?

People also ask

Does every view need a controller?

Absolutely not. Design your application in a logical and consistent way. A controller usually handles many actions and returns many different views. You could consider having a FAQController to render all the views, for both user and admin.

How does the controller in MVC work?

A controller is responsible for controlling the way that a user interacts with an MVC application. A controller contains the flow control logic for an ASP.NET MVC application. A controller determines what response to send back to a user when a user makes a browser request.

How are controllers instantiated?

New controller is instantiated on each HTTP request. The instantiation is in-directed, means first we retrieve Type, after creating Instance. The type is being searched dynamically by getting out reflection information from assemblies.


A Controller is created for every request by the ControllerFactory (which by default is the DefaultControllerFactory).

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

Note that the Html.Action Html Helper will create another controller.

The short version is that ControllerActivator.Create is called (for every request) to create a Controller (which inits a new Controller either through the DependencyResolver or through the Activator if no Resolver has been set up):

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

The longer version is this (Here's the code from the source 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));
    }
}

Here's the Controller factory code:

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

Which basically calls this:

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

Which calls this method in the ControllerActivator (This code tries to ask the DependencyResolver for an instance, or just uses the Activator class):

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

This might fall under too much information... But I wanted to show that you really DO get a new controller for EVERY request.


I created an empty constructor for a controller and put a break point in the constructor. It got hit every time there was a new request. So I think it's created for every request.


The controller will be created when any Action in a specific Controller is performed.

I have a project where all of my Controllers inherit from an ApplicationController and every time that an action is performed, the breakpoint is hit inside of the ApplicationController - regardless of its "current" Controller.

I initialize my agent (which works as my context) whenever my controller is created like such:

    public IWidgetAgent widgetAgent { get; set; }

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

    }

This is obviously not what you need - as you mentioned that you only wanted a single instance each time it was called. But it is a good place to check what is going on each time and to ensure that another instance of your context does not currently exist.

Hope this helps.


Controllers are created for every request. The magic happens in the routing in the gobal.aspx. The mapping paths direct MVC to which controller to create and action on the controller to call, and parameters to pass to them.

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