ASP.NET MVC: контроллер создается для каждого запроса?


очень простой вопрос: есть ли контроллеры в ASP.NET создается для каждого HTTP-запроса, или они создаются при запуске приложения и повторно используются во всех запросах?

будет ли контроллер создан только для конкретного HTTP-запроса?

Если мои предыдущие предположения верны, могу ли я на это положиться? Я хочу создать контекст базы данных (Entity Framework), который будет жить только для одного запроса. Если я создаю его как свойство инициализируется в конструкторе контроллера, это предоставлено, что новый экземпляр контекста будет создан для каждого запроса?

4 79

4 ответа:

контроллер создается для каждого запроса ControllerFactory (который по умолчанию является DefaultControllerFactory).

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

отметим, что Html.Action HTML-код помощника будет создан еще один контроллер.

короткая версия заключается в том, что ControllerActivator.Create вызывается (для каждого запроса) для создания контроллера (который вводит новый контроллер либо через 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 для экземпляра, или просто использует активатор класс):

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

это может попасть под слишком много информации... Но я хотел показать, что вы действительно получаете новый контроллер для каждого запроса.

Я создал пустой конструктор для контроллера и поставить точку останова в конструкторе. Он получал удар каждый раз, когда был новый запрос. Поэтому я думаю, что он создан для каждого запроса.

контроллер будет создан при выполнении любого действия в конкретном контроллере.

у меня есть проект, где все мои контроллеры наследовать от ApplicationController и каждый раз, когда выполняется действие, останова внутри ApplicationController - независимо от ее "настоящее контроллер".

Я инициализирую свой агент (который работает как мой контекст) всякий раз, когда мой контроллер создается так:

    public IWidgetAgent widgetAgent { get; set; }

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

    }

Это явно не то, что вам нужно - как вы упомянули, что вы хотели только один экземпляр каждый раз, когда его называли. Но это хорошее место, чтобы проверить, что происходит каждый раз и гарантировать, что другой экземпляр контекста в настоящее время не существует.

надеюсь, что это помогает.

контроллеры создаются для каждого запроса. Волшебство происходит в маршрутизации в гобал.aspx. Пути сопоставления направляют MVC к контроллеру для создания и действия на контроллере для вызова, а также параметры для передачи им.

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