【问题标题】:ASP.NET MVC Controller LifecycleASP.NET MVC 控制器生命周期
【发布时间】:2009-11-19 14:45:40
【问题描述】:

据我了解,在每次 Web 请求期间都不会调用控制器的构造函数。假设这是真的,控制器的生命周期是什么?是在应用启动时“构建”,然后通过每个 Web 请求注入的 requestcontext 进行缓存和调用吗?

为了清楚起见,我不是在问如何模拟构造函数的行为,我使用 OnActionExecuting 事件来启动我通常在构造函数中执行的操作。此外,我确实在控制器上使用构造函数进行单元和系统测试。

谢谢!

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    如果您使用default controller factory,将为每个请求构建一个新实例,这就是应该的方式。控制器不应该在不同的请求之间共享。您可以编写一个自定义工厂来管理控制器的生命周期。

    【讨论】:

    • 我搞砸了并自学了为什么会这样并且应该这样。我正在使用 EF 创建具有读/写操作和视图的控制器。生成的代码为 EF Context 实例创建了一个私有实例变量。我想我会很聪明,把它变成一个静态变量。问题是如果这个控制器范围之外的东西修改了数据库,静态上下文永远不会知道。现在我将其保留为实例变量,并且由于每个请求都会创建一个新实例,因此上下文可以看到对数据库的任何更改。
    • 在所有状态都包含在参数中(即功能样式)的 Web API 中,没有理由(我可以看到)为什么不能重用控制器。它在设计上是线程安全的。
    • @ChrisOldwood 仅仅因为 API 是无状态的并不意味着底层代码是无状态的。可能有记录器或其他实用程序在控制器构造时实例化,这些对象可以跨请求重用。
    • @JoshKodroff 另一种方法是创建必须是线程安全的控制器,因为不同线程之间的不同请求访问同一个控制器。你能保证控制器的所有依赖项也是如此吗?您的整个应用程序或多或少必须是线程安全的。
    【解决方案2】:

    恐怕你的理解是错误的。控制器(应该是一个非常轻量级的类,并且不能有任何会话过期状态)实际上是为每个 Web 请求动态构建的。控制器实例如何才能特定于某个视图?

    所以没有所谓的“生命周期”(除了请求的生命周期)......

    【讨论】:

    • 是的,肯定存在某种“生命周期”。在我的控制器中,我为所有帐户创建一个 linq 表达式,然后使用 this.Ok(accounts) 返回。在控制器方法执行后的某个时间,在帐户集合上调用 IEnumerator,所以,是的,肯定需要考虑一个提升时间。
    【解决方案3】:

    为您执行的每个请求创建一个控制器。举个例子吧。

       public class ExampleController : Controller{
               public static userName;
    
                public void Action1(){//do stuff}
                public void Action2(){//do stuff}
                public void AssignUserName(string username){
                     userName = username;
    
                }
               public string GetName(){ return userName;}
    
    
       }
    

    现在您可以从传递用户名的视图调用控制器。不要指望在下一个请求中得到你设置的用户名。它将返回空值。因此,对于每个请求,都会创建一个新控制器。您不会在 MVC 中的任何地方实例化控制器,就像从类中实例化对象一样。只是你没有控制器对象内存指针来调用它,就像你对其他对象所做的那样。

    转到此链接。关于 MVC 控制器的生命周期有一个很好的解释。

    ASP.Net MVC - Request Life Cycle

    【讨论】:

    • 我不是 MVC 专业人士,但这不是我现在正在开发的 MVC 应用程序中看到的行为。我有一个声明为public class ClassName : Controller 的控制器,它有一个静态成员static string PropertyName = "";。我发现存储在静态属性中的任何内容都会在请求中保留在那里。为什么我会看到这个?
    • @andyb 因为它是静态的,线程可以重用,但不能保证
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多