ASP.NET MVC: Bộ điều khiển có được tạo cho mọi yêu cầu không?


112

Câu hỏi rất đơn giản: Bộ điều khiển trong ASP.NET được tạo cho mọi yêu cầu HTTP hay chúng được tạo khi khởi động ứng dụng và được sử dụng lại trong các yêu cầu?

Bộ điều khiển có được tạo chỉ cho một yêu cầu HTTP cụ thể không?

Nếu những giả định trước đây của tôi là đúng, tôi có thể phụ thuộc vào nó không? Tôi muốn tạo ngữ cảnh cơ sở dữ liệu (Entity Framework) sẽ chỉ tồn tại cho một yêu cầu. Nếu tôi tạo nó như một thuộc tính được khởi tạo trong phương thức khởi tạo của controller, thì nó có được cấp phép rằng phiên bản ngữ cảnh mới sẽ được tạo cho mọi yêu cầu không?


16
Đặt một breakpoint trong constructor của bạn và xem những gì bạn có thể tìm hiểu ...
Greg B

10
@ Greg B: ý tưởng tuyệt vời ngoại trừ nó sẽ không cho tôi biết nếu nó cư xử như thế luôn - nếu hoàn cảnh thay đổi và một số điều khiển sẽ thay đổi hành vi của nó tôi có lỗi mà có thể được thực sự khó tìm ...
Rasto

@drasto bạn sẽ kiểm tra xem nó có hoạt động như vậy luôn không? Kiểm tra mọi yêu cầu đối với ứng dụng của bạn?
Greg B

4
@Todd Smith xin vui lòng một số liên kết hoặc ít nhất là tên đầy đủ. Chữ cây IoC rất khó để google. Cảm ơn bạn.
Rasto

2
@drasto IoC = Đảo ngược quyền kiểm soát en.wikipedia.org/wiki/Inversion_of_control
Bala R

Câu trả lời:


103

Bộ điều khiển được tạo cho mọi yêu cầu bởi ControllerFactory(theo mặc định là DefaultControllerFactory).

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

Lưu ý rằng Html.ActionTrình trợ giúp Html sẽ tạo một bộ điều khiển khác.

Phiên bản ngắn ControllerActivator.Createđược gọi (cho mọi yêu cầu) để tạo Bộ điều khiển (tạo Bộ điều khiển mới thông qua DependencyResolver hoặc thông qua Trình kích hoạt nếu chưa thiết lập Bộ phân giải):

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

Đây là phiên bản dài hơn (Đây là mã từ nguồn từ 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));
    }
}

Đây là mã xuất xưởng của Bộ điều khiển:

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

Về cơ bản gọi đây là:

protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
{
    return ControllerActivator.Create(requestContext, controllerType);
}

Phương thức nào gọi phương thức này trong ControllerActivator(Mã này cố gắng hỏi DependencyResolver cho một phiên bản hoặc chỉ sử dụng lớp Activator):

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

Điều này có thể thuộc về quá nhiều thông tin ... Nhưng tôi muốn chứng minh rằng bạn thực sự CÓ THỂ nhận được một bộ điều khiển mới cho MỌI yêu cầu.



32

Tôi đã tạo một hàm tạo trống cho một bộ điều khiển và đặt một điểm ngắt trong hàm tạo. Nó bị tấn công mỗi khi có một yêu cầu mới. Vì vậy, tôi nghĩ rằng nó được tạo ra cho mọi yêu cầu.


3
+1 Tôi hy vọng bạn đúng nhưng tôi muốn một số kiến ​​thức được phê duyệt tốt hơn chỉ là "trong mọi trường hợp tôi đã thử nó đều hoạt động". Nếu đôi khi nó không hoạt động như vậy từ một số lý do thì nó có nghĩa là một lỗi.
Rasto

6
@drasto: Không cần lo lắng. Bộ điều khiển được khởi tạo cho mọi yêu cầu. Mặc dù vậy, một số bộ nhớ sẽ được sử dụng lại nhưng bạn không nên lo lắng về trạng thái bộ điều khiển (nếu bộ điều khiển của bạn có). Nó sẽ được khởi tạo như mong đợi. Nhưng có thể có một tình huống trong đó nhiều hơn một bộ điều khiển sẽ được khởi tạo. Và đó là khi lượt xem các hành động của bộ điều khiển cuộc gọi (tức là. Html.RenderAction("action", "controller");)
Robert Koritnik

@RobertKoritnik & Bala R, tôi có một câu hỏi vui lòng. Điều gì xảy ra đối với các đối tượng được tạo như Sinh viên hoặc Danh sách <Sinh viên> sau khi phương thức hành động đã phân phát nó hoặc chúng đến dạng xem? Chúng có bị xử lý không? Và điều gì sẽ xảy ra với những đối tượng này khi một yêu cầu mới đến?
Mahdi Alkhatib

3

Bộ điều khiển sẽ được tạo khi bất kỳ Hành động nào trong Bộ điều khiển cụ thể được thực hiện.

Tôi có một dự án trong đó tất cả các Bộ điều khiển của tôi kế thừa từ một ApplicationControllervà mỗi khi một hành động được thực hiện, điểm ngắt được nhấn vào bên trong ApplicationController- bất kể Bộ điều khiển " hiện tại " của nó là gì .

Tôi khởi tạo tác nhân của mình (hoạt động như ngữ cảnh của tôi) bất cứ khi nào bộ điều khiển của tôi được tạo như vậy:

    public IWidgetAgent widgetAgent { get; set; }

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

    }

Đây rõ ràng không phải là thứ bạn cần - như bạn đã đề cập rằng bạn chỉ muốn một phiên bản duy nhất mỗi khi nó được gọi. Nhưng đó là một nơi tốt để kiểm tra những gì đang xảy ra mỗi lần và đảm bảo rằng một phiên bản khác của ngữ cảnh của bạn hiện không tồn tại.

Hi vọng điêu nay co ich.


2

Bộ điều khiển được tạo cho mọi yêu cầu. Điều kỳ diệu xảy ra trong quá trình định tuyến trong gobal.aspx. Các đường dẫn ánh xạ hướng MVC tới bộ điều khiển nào để tạo và hành động trên bộ điều khiển để gọi và các tham số để chuyển cho chúng.

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


cần trích dẫn - không thể tìm thấy thông tin hỗ trợ trong tài liệu được liên kết. Cảm ơn bạn
Rasto
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.