ASP.NET MVC 控制器生命周期
Posted
技术标签:
【中文标题】ASP.NET MVC 控制器生命周期【英文标题】:ASP.NET MVC Controller Lifecycle 【发布时间】:2009-11-19 14:45:40 【问题描述】:据我了解,在每次 Web 请求期间都不会调用控制器的构造函数。假设这是真的,控制器的生命周期是什么?是在应用启动时“构建”,然后通过每个 Web 请求注入的 requestcontext 进行缓存和调用吗?
为了清楚起见,我不是在问如何模拟构造函数的行为,我使用 OnActionExecuting 事件来启动我通常在构造函数中执行的操作。此外,我确实在控制器上使用构造函数进行单元和系统测试。
谢谢!
【问题讨论】:
【参考方案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 因为它是静态的,线程可以重用,但不能保证以上是关于ASP.NET MVC 控制器生命周期的主要内容,如果未能解决你的问题,请参考以下文章