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

.Netasp.net Mvc-3Entity FrameworkControllerHttprequest

.Net Problem Overview


Very simple question: Are controllers in ASP.NET created for every HTTP request, or are they created at application startup and reused throughout requests?

Will the controller be created only for a particular HTTP request?

If my previous assumptions are correct, can I depend on it? I want to create database context (Entity Framework) that will live only for one request. If I create it as a property initialized in controller's constructor, is it granted that new instance of context will be created on for every request?

.Net Solutions


Solution 1 - .Net

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.

Solution 2 - .Net

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.

Solution 3 - .Net

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.

Solution 4 - .Net

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRastoView Question on Stackoverflow
Solution 1 - .NetLinkgoronView Answer on Stackoverflow
Solution 2 - .NetBala RView Answer on Stackoverflow
Solution 3 - .NetRion WilliamsView Answer on Stackoverflow
Solution 4 - .NetBlackICEView Answer on Stackoverflow