MVC Life Cycle - Part Four

Before reading this article, I highly recommend you read my previous parts:

This is the continuation of the MVC Life Cycle Series. If you are referring this article as a standalone, I would encourage you to go through the entire series in order to understand the entire gist of the same.

In this section, we are going to see how Controllers are created and initialized. Basically, controllers do nothing but implement IController interface. IController defines one important method called Execute(). Also, it is important to note that this method is entirely generic which means you can build your controller in a more custom way specific to particular requirement. However, MVC is very powerful framework wherein all the concerns are already addressed. But, you can extend the default implementation for any specific need.

Here, ControllerFactory here comes into picture. Here, it is used by MVCHandler. Now, ControllerFactory's primary responsibility is to provide appropriate type of controller to service the request. Again, ControllerFactory is tied with IControllerFactory. Hence, without wasting time, let us go ahead and jump to the demo. In the following snippet, I have created one sample controller and implemented IController here.
  1. using System;    
  2. using System.Web.Mvc;    
  3. using System.Web.Routing;    
  4.     
  5. namespace MVC_Life_Cycle.Controllers    
  6. {    
  7.     public class SampleController : IController    
  8.     {    
  9.         public void Execute(RequestContext requestContext)    
  10.         {    
  11.             throw new NotImplementedException();    
  12.         }    
  13.     }    
  14. }   
Above snippet is the raw snippet obviously. Now, let us go ahead and modify the same.
  1. using System;    
  2. using System.Net.Http;    
  3. using System.Web;    
  4. using System.Web.Mvc;    
  5. using System.Web.Routing;    
  6.     
  7. namespace MVC_Life_Cycle.Controllers    
  8. {    
  9.     public class SampleController : IController    
  10.     {    
  11.         public void Execute(RequestContext requestContext)    
  12.         {    
  13.             //Displaying some message    
  14.             HttpContext.Current.Response.Write("Hello From Custom Controller Implementation");    
  15.         }    
  16.     }    
  17. }  
Now, let us go ahead and create one controller factory which will basically implement our custom controller. Now, you may be thinking there are lots of stuff going here, which is true by the way in this context.
  1. using System.Web.Mvc;    
  2. using System.Web.Routing;    
  3. using System.Web.SessionState;    
  4.     
  5. namespace MVC_Life_Cycle.CustomFactory    
  6. {    
  7.     public class CustomFactory :IControllerFactory    
  8.     {    
  9.         public IController CreateController(RequestContext requestContext, string controllerName)    
  10.         {    
  11.             throw new System.NotImplementedException();    
  12.         }    
  13.     
  14.         public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)    
  15.         {    
  16.             throw new System.NotImplementedException();    
  17.         }    
  18.     
  19.         public void ReleaseController(IController controller)    
  20.         {    
  21.             throw new System.NotImplementedException();    
  22.         }    
  23.     }    
  24. }   
Here you can see that controller factory implements three methods wherein, the first one is for controller creation, the third one is for session maintenance, and the third one is obviously for releasing the controller.
  1. using System.Web.Mvc;    
  2. using System.Web.Routing;    
  3. using System.Web.SessionState;    
  4. using MVC_Life_Cycle.Controllers;    
  5.     
  6. namespace MVC_Life_Cycle.CustomFactory    
  7. {    
  8.     public class CustomFactory :IControllerFactory    
  9.     {    
  10.         public IController CreateController(RequestContext requestContext, string controllerName)    
  11.         {    
  12.             //Finds the controller with its name and then bring the logic here    
  13.             if (controllerName == "Sample")    
  14.             {    
  15.                 return new SampleController();    
  16.             }    
  17.             else    
  18.             {    
  19.                 //Else return the existing one    
  20.                 return new HomeController();    
  21.             }    
  22.         }    
  23.     
  24.         //These two implementations are not required for the time being. Hence, kept the default values    
  25.         public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)    
  26.         {    
  27.            return SessionStateBehavior.Default;    
  28.         }    
  29.     
  30.         public void ReleaseController(IController controller)    
  31.         {    
  32.             //Since, this is void method. Hence, left empty for the time being    
  33.         }    
  34.     }    
  35. }   
Now, in order to register the same, I need to make the changes in global.asax file itself.
  1. using System.Diagnostics;    
  2. using System.Web;    
  3. using System.Web.Mvc;    
  4. using System.Web.Optimization;    
  5. using System.Web.Routing;    
  6. using MVC_Life_Cycle;    
  7. using MVC_Life_Cycle.CustomModules;    
  8.     
  9. [assembly: PreApplicationStartMethod(typeof(MvcApplication), "RegisterCustomModule")]    
  10. namespace MVC_Life_Cycle    
  11. {    
  12.     public class MvcApplication : System.Web.HttpApplication    
  13.     {    
  14.         public static void RegisterCustomModule()    
  15.     
  16.         {    
  17.             HttpApplication.RegisterModule(typeof(CustomModule));    
  18.         }    
  19.         protected void Application_Start()    
  20.         {    
  21.             //Registering that custom controller    
  22.             ControllerBuilder.Current.SetControllerFactory(new CustomFactory.CustomFactory());    
  23.             AreaRegistration.RegisterAllAreas();    
  24.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);    
  25.             RouteConfig.RegisterRoutes(RouteTable.Routes);    
  26.             BundleConfig.RegisterBundles(BundleTable.Bundles);    
  27.         }    
  28.     
  29.         protected void Application_End()    
  30.         {    
  31.             Debug.WriteLine("Application Stopped");    
  32.         }    
  33.     }    
  34. }   
With the above change in place, when I run the app and navigate to URL http://localhost:44694/Sample, then it will produce the following output.


And then it will produce the default result.


I hope you have liked this discussion. I will continue to delve further in coming session. Until then, stay tuned and happy coding.

Code Download Link.