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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5425920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 15:24:12  来源:igfitidea点击:

ASP.NET MVC: Is Controller created for every request?

.netasp.net-mvc-3entity-frameworkcontrollerhttprequest

提问by Rasto

Very simple question: Are controllers in ASP.NET created for every HTTP request, or are they created at application startup and reused throughout requests?

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

Will the controller be created only for a particular HTTP request?

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

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?

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

采纳答案by Linkgoron

A Controller is created for every request by the ControllerFactory(which by default is the DefaultControllerFactory).

为每个请求创建一个控制器ControllerFactory(默认情况下是DefaultControllerFactory)。

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

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

Note that the Html.ActionHtml Helper will create another controller.

请注意,Html.ActionHtml Helper 将创建另一个控制器。

The short version is that ControllerActivator.Createis 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):

简短版本是ControllerActivator.Create调用(对于每个请求)来创建一个控制器(它通过 DependencyResolver 或如果没有设置 Resolver 则通过 Activator 初始化一个新的控制器):

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):

更长的版本是这样的(这是来自 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):

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

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.

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

回答by Bala R

I created an empty constructor for a controller and put a break point in the constructor. It got hit every time there was a new request. So I think it's created for every request.

我为控制器创建了一个空的构造函数,并在构造函数中放置了一个断点。每次有新请求时,它都会受到攻击。所以我认为它是为每个请求创建的。

回答by Rion Williams

The controller will be created when any Action in a specific Controller is performed.

当执行特定控制器中的任何操作时,将创建控制器。

I have a project where all of my Controllers inherit from an ApplicationControllerand every time that an action is performed, the breakpoint is hit inside of the ApplicationController- regardless of its "current" Controller.

我有一个项目,其中我的所有控制器都继承自一个,ApplicationController并且每次执行操作时,断点都会在ApplicationController- 无论其“当前”控制器如何。

I initialize my agent (which works as my context) whenever my controller is created like such:

每当我的控制器像这样创建时,我都会初始化我的代理(作为我的上下文):

    public IWidgetAgent widgetAgent { get; set; }

    public WidgetController()
    {
        if (widgetAgent == null)
        {
            widgetAgent = new WidgetAgent();
        }

    }

This is obviously not what you need - as you mentioned that you only wanted a single instance each time it was called. But it is a good place to check what is going on each time and to ensure that another instance of your context does not currently exist.

这显然不是您需要的 - 正如您提到的,每次调用它时您只需要一个实例。但这是检查每次发生的情况并确保当前不存在上下文的另一个实例的好地方。

Hope this helps.

希望这可以帮助。

回答by BlackICE

Controllers are created for every request. The magic happens in the routing in the gobal.aspx. The mapping paths direct MVC to which controller to create and action on the controller to call, and parameters to pass to them.

为每个请求创建控制器。神奇发生在 gobal.aspx 的路由中。映射路径将 MVC 引导到要创建的控制器和要调用的控制器上的操作,以及要传递给它们的参数。

http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb

http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-vb