78

It's my understanding that the constructor for a controller is not called during each web request. Assuming this is true, what is the lifecycle of a controller? Is is "constructed" upon app start, then cached and invoked with the requestcontext injected into it with each web request?

Just to be clear, I'm not asking how to emulate constructor behavior, I use the OnActionExecuting event to initiate things I would normally do in a constructor. Also, I do use constructors on controllers for unit and system testing.

Thanks!

tereško
  • 58,060
  • 25
  • 98
  • 150
Josh Pearce
  • 3,399
  • 1
  • 23
  • 24

3 Answers3

102

If you use the default controller factory a new instance will be constructed for each request and that's the way it should be. Controllers shouldn't be shared among different requests. You could though write a custom factory that manages the lifetime of the controllers.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 3
    I screwed up and taught myself why this is and should be the case. I was creating controllers with read/write actions and views using EF. The generated code created a private instance variable for the EF Context instance. I thought I would be smart and make that a static variable. The problem is that if something outside of the scope of this controller modifies the database, the static context never knows. Now I leave it as an instance variable and since a new instance is created with each request, the context can see any changes to the database. – ThatAintWorking Jun 19 '13 at 18:38
  • 3
    In a Web API where all the state is contained within parameters (i.e. a functional style) there is no reason (that I can see) why a controller cannot be reused. It is thread-safe by design. – Chris Oldwood Sep 19 '13 at 09:10
  • 10
    @ChrisOldwood just because the API is stateless doesn't mean the underlying code is stateless. There may be loggers or other utilities that are instantiated at controller construction which object to being reused across requests. – ehdv Jan 23 '14 at 18:45
  • @JoshKodroff The alternative is creating controllers that have to be threadsafe, as different requests across different threads access the same controller. Can you gurantee that for all dependencies of the controller as well? Your entire application will more or less have to be threadsafe. – arynaq Jan 29 '20 at 12:23
18

I'm afraid, your understanding is wrong. A controller (which should be a very thin and lightweight class and must not have any session-outliving state) is actually constructed on the fly for each and every web request. How else could a controller instance be specific to a certain view?

So there is no such thing as a "lifecycle" (other than that of the request)...

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34
  • 1
    Yes, there is definitely something of a 'lifecycle' going on. In my controller I create a linq expression for all the accounts, then I return using **this.Ok(accounts)**. Sometime after the controller methods execute, The IEnumerator is called on the accounts collection, so, yeah, there's definitely a liftetime that needs to be considered. – Quark Soup Nov 18 '18 at 23:07
7

A controller is created for every request you do. Lets take an example.

   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;}


   }

Now you can call the controller from the view passing a username. Don't hope to get the userName you set in the next request. it will return null. Thus for every request a new controller is created. You don't instantiate a controller anywhere in MVC like you instatiate an object from a class. Simply you don't have controller object memory pointer to call it as you do with other objects.

Go to this link. There is a good explanation on lifecycle of MVC controller.

ASP.Net MVC - Request Life Cycle

Community
  • 1
  • 1
  • 1
    I'm not an MVC pro, but this is not the behavior I see in the MVC app I'm working on right now. I have a controller declared as `public class ClassName : Controller` with a static member, `static string PropertyName = "";`. I find that whatever is stored in the static property remains there across requests. Why would I see this? – andyb Jan 30 '19 at 03:51
  • @andyb since it is static and threads can be resused, no guarantee though – NeutronCode Jun 27 '19 at 12:04