ASP.NET MVC:是否为每个请求创建了控制器?

Ras*_*sto 98 .net entity-framework controller httprequest asp.net-mvc-3

非常简单的问题:ASP.NET中的控制器是为每个HTTP请求创建的,还是在应用程序启动时创建并在整个请求中重用?

是否只为特定的HTTP请求创建控制器?

如果我之前的假设是正确的,我可以依赖它吗?我想创建仅适用于一个请求的数据库上下文(实体框架).如果我将它创建为在控制器的构造函数中初始化的属性,是否会为每个请求创建新的上下文实例?

Lin*_*ron 92

ControllerFactory为每个请求创建一个Controller(默认情况下是DefaultControllerFactory).

http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultcontrollerfactory.aspx

请注意,ControllerFactoryHtml Helper将创建另一个控制器.

简短的版本是,DefaultControllerFactory被称为(为每个请求)来创建一个控制器(通过DependencyResolver或通过激活,如果没有解决程序已经设置了哪些inits一个新的控制器):

public IController Create(RequestContext requestContext, Type controllerType) 
{
    try 
    {
        return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
    }
Run Code Online (Sandbox Code Playgroud)

更长的版本是这里(这是来自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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Controller工厂代码

public virtual IController CreateController(RequestContext requestContext, string controllerName) 
{
    Type controllerType = GetControllerType(requestContext, controllerName);
    IController controller = GetControllerInstance(requestContext, controllerType);
    return controller;
}
Run Code Online (Sandbox Code Playgroud)

这基本上叫做:

protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
{
    return ControllerActivator.Create(requestContext, controllerType);
}
Run Code Online (Sandbox Code Playgroud)

哪个在ControllerActivator中调用此方法(此代码尝试向DependencyResolver询问实例,或者仅使用Activator类):

public IController Create(RequestContext requestContext, Type controllerType) 
{
    try 
    {
        return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
    }
Run Code Online (Sandbox Code Playgroud)

这可能属于太多的信息.​​.....但我想证明你确实为每个请求获得了一个新的控制器.


Bal*_*a R 28

我为控制器创建了一个空构造函数,并在构造函数中放置了一个断点.每当有新请求时它就会被击中.所以我认为它是为每个请求创建的.

  • @drasto:不用担心.控制器为每个请求实例化.虽然有些内存会被重用但你不应该担心控制器状态(如果有的话).它将按预期初始化.**但是**可能会出现多个控制器被实例化的情况.那就是当视图调用控制器动作时(即`Html.RenderAction("action","controller");`) (6认同)
  • +1我希望你是对的,但我想要一些更好的认可知识,而不仅仅是"在所有情况下我都尝试过它".如果它有时因某种原因不能起作用,那就意味着一个bug. (2认同)