ASP.NET MVC:是否为每个请求创build了Controller?
非常简单的问题:ASP.NET中的控制器是为每个HTTP请求创build的,还是在应用程序启动时创build并在整个请求中重用?
是否仅为特定的HTTP请求创build控制器?
如果我以前的假设是正确的,我可以依靠它吗? 我想创build数据库上下文(entity framework),将只生活一个请求。 如果我将其创build为在控制器的构造函数中初始化的属性,是否会为每个请求创build新的上下文实例?
ControllerFactory为每个请求创build一个Controller(默认为DefaultControllerFactory)。
http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx
请注意, Html.Action
Html Helper将创build另一个控制器。
简短版本是调用ControllerActivator.Create
(为每个请求)来创build一个控制器(如果没有设置Resolver,则通过DependencyResolver或激活器进入新控制器):
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)); }
这可能会属于太多的信息...但是我想表明,你真的得到一个新的控制器为每个请求。
我为控制器创build了一个空的构造函数,并在构造函数中放置了一个断点。 每次有新的要求时都会被打到。 所以我认为它是为每个请求创build的。
控制器将在执行特定控制器中的任何操作时创build。
我有一个项目,其中的所有控制器都从ApplicationController
inheritance,每次执行操作时,都会在ApplicationController
内部触发断点 – 无论其“ 当前 ”控制器如何。
我初始化我的代理(这工作作为我的上下文),只要我的控制器是这样创build的:
public IWidgetAgent widgetAgent { get; set; } public WidgetController() { if (widgetAgent == null) { widgetAgent = new WidgetAgent(); } }
这显然不是你所需要的 – 正如你所提到的,每次调用时你只需要一个实例。 但是,这是一个很好的地方,可以检查每次发生的情况,并确保当前情况的另一个实例不存在。
希望这可以帮助。
控制器是为每个请求创build的。 神奇的发生在gobal.aspx的路由中。 映射path指导控制器创build的MVC以及控制器要调用的动作,以及传递给它们的参数。
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb