非常简单的问题:ASP.NET中的控制器是为每个HTTP请求创建的,还是在应用程序启动时创建并在整个请求期间重复使用?
控制器只会为特定的HTTP请求创建吗?
如果我的之前的假设是正确的,那么我可以依赖它吗?我想创建一个数据库上下文(Entity Framework),它仅在一个请求中存在。如果我将其作为在控制器构造函数中初始化的属性创建,那么新的上下文实例是否保证仅在每个请求中创建一次?
非常简单的问题:ASP.NET中的控制器是为每个HTTP请求创建的,还是在应用程序启动时创建并在整个请求期间重复使用?
控制器只会为特定的HTTP请求创建吗?
如果我的之前的假设是正确的,那么我可以依赖它吗?我想创建一个数据库上下文(Entity Framework),它仅在一个请求中存在。如果我将其作为在控制器构造函数中初始化的属性创建,那么新的上下文实例是否保证仅在每个请求中创建一次?
每个请求都会由ControllerFactory
(默认情况下为DefaultControllerFactory
)创建一个控制器。
http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx
请注意,Html.Action
Html Helper将创建另一个控制器。ControllerActivator.Create
会被调用(对于每个请求),以创建一个控制器(通过DependencyResolver或如果没有设置解析器,则通过Activator初始化新的控制器):public IController Create(RequestContext requestContext, Type controllerType)
{
try
{
return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
}
更详细的版本如下(以下是来自 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));
}
}
以下是控制器工厂的代码:
public virtual IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType = GetControllerType(requestContext, controllerName);
IController controller = GetControllerInstance(requestContext, controllerType);
return controller;
}
这基本上调用了这个:
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return ControllerActivator.Create(requestContext, controllerType);
}
这个方法在ControllerActivator
中被调用(这段代码尝试向DependencyResolver请求一个实例,或者直接使用Activator类):
public IController Create(RequestContext requestContext, Type controllerType)
{
try
{
return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
}
这可能属于太多的信息...但我想表明,您确实会为每个请求获得一个新的控制器。
我为控制器创建了一个空构造函数,并在其中设置了断点。每当有新的请求时,它都会被触发。因此,我认为它是为每个请求创建的。
Html.RenderAction("action", "controller")
)。 - Robert Koritnik当执行特定控制器中的任何操作时,将创建控制器。
我的项目中,所有控制器都继承自ApplicationController
,每次执行操作时,断点都会命中在ApplicationController
中 - 不管它的"当前"控制器是什么。
我像这样在创建控制器时初始化我的代理(作为我的上下文):
public IWidgetAgent widgetAgent { get; set; }
public WidgetController()
{
if (widgetAgent == null)
{
widgetAgent = new WidgetAgent();
}
}
每个请求都会创建控制器。魔法发生在Global.aspx中的路由中。映射路径指向MVC应创建哪个控制器以及要调用的控制器上的操作和要传递给它们的参数。
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb