非常简单的问题:是在ASP.NET中为每个HTTP请求创建控制器,还是在应用程序启动时创建并在整个请求中重用这些控制器?
是否仅针对特定的HTTP请求创建控制器?
如果我以前的假设是正确的,我可以依靠它吗?我想创建仅对一个请求有效的数据库上下文(实体框架)。如果我将其创建为在控制器的构造函数中初始化的属性,是否是否将为每个请求创建新的上下文实例?
非常简单的问题:是在ASP.NET中为每个HTTP请求创建控制器,还是在应用程序启动时创建并在整个请求中重用这些控制器?
是否仅针对特定的HTTP请求创建控制器?
如果我以前的假设是正确的,我可以依靠它吗?我想创建仅对一个请求有效的数据库上下文(实体框架)。如果我将其创建为在控制器的构造函数中初始化的属性,是否是否将为每个请求创建新的上下文实例?
Answers:
会为每个请求创建一个控制器ControllerFactory
(默认为DefaultControllerFactory
)。
http://msdn.microsoft.com/zh-CN/library/system.web.mvc.defaultcontrollerfactory.aspx
请注意,Html.Action
HTML Helper将创建另一个控制器。
简短的版本是ControllerActivator.Create
(针对每个请求)调用以创建控制器(如果没有设置解析器,则可以通过DependencyResolver或通过Activator来初始化新的Controller):
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));
}
}
这是Controller的工厂代码:
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");
)
当执行特定控制器中的任何操作时,将创建该控制器。
我有一个项目,我的所有Controller都继承自一个项目,ApplicationController
并且每次执行操作时,ApplicationController
都会在-的内部命中断点,而不管其“ 当前 ” Controller如何。
每当创建控制器时,我都会初始化代理(作为上下文):
public IWidgetAgent widgetAgent { get; set; }
public WidgetController()
{
if (widgetAgent == null)
{
widgetAgent = new WidgetAgent();
}
}
显然这不是您所需要的-正如您提到的,每次调用它只需要一个实例。但这是检查每次发生的情况并确保当前不存在上下文的另一个实例的好地方。
希望这可以帮助。
为每个请求创建控制器。魔术发生在gobal.aspx中的路由中。映射路径将MVC定向到要创建的控制器并调用该控制器上的操作,并将参数传递给它们。
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb