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?
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.