CustomControllerFactory in MVC4

Here, we will implement CustomControllerFactory Interface and methods which does the loading and creation of controller.

Whenever the request comes from the users, it is processed in the following sequence in order to render the view to the user.

sequence

As we can see from the above diagram whenever a request comes from the user, first it goes to the routing system then it is transferred to the ControllerFactory which internally decides which controller to call and then in turn which action to be invoked is decided by the controller, so that the requested view is returned to the user. In this case every request coming from the user has to go through the ControllerFactory. Now you must be wondering we’d not created any ContollerFactory in our application well that rights ASP.Net MVC provides you with the default ContorllerFactory which does the work of finding the appropriate controller and processing your request. The "DefaultControllerFactory" is the class provided by mvc as a ControllerFactory. It basically implements the interface "IControllerFactory" which has certain methods which does the loading and creation of controller. Following are the methods defined inside "IControllerFactory" interface.
  1. IController CreateController(RequestContext requestContext, string controllerName)
  2. SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
  3. void ReleaseController(IController controller)

Well Microsoft has provided you with the benefit of flexibility so that you can change the default behavior of working with mvc to your own customizable way. Here the example just demonstrate that you can change the default working of ControllerFactory to the way you defined, by just creating a class which implements the IContollerFactory interface. But this is not the ideal way for doing things that because if you try to implement your own ControllerFactory you need to make sure about the various issues that may occur during execution and working of your controller. Issues like

  • Properly handling user request and loading the right Controller which is required
  • Loading the controller dynamically
  • Resolving the ambiguity issues arising because of same class name within different namespaces.
  • Handling exception which may occur during runtime

Note

  1. This is just a demonstration to known/ understand that we can incorporate our own implementation logic in creation of controllers. By creating a class which in turn implements the IControllerFactory interface.
  2. If you take my view, then the built in "DefaultControllerFactory" is best one to use for some scenarios where the things to be done are not that complex.
  3. Well some developer makes use of customized controller factory for doing dependency injection via constructors or for writing their own way for processing a request.

Ok now let’s start with the creation of the "CustomizeControllerFactory class". For this I’ve just added a new folder with the name “Infrastructure” in the application.

Here is the code snippet for the same.

  1. public class CustomControllerFactory : IControllerFactory  
  2. {  
  3.     /// <summary>  
  4.     /// This is the main method which is used for creation and dynamic loading of the controller.  
  5.     /// </summary>  
  6.     /// <param name="requestContext">Request Context Object(to get the details of the request)</param>  
  7.     /// <param name="controllerName">Controller Name from the routed url</param>  
  8.     /// <returns>Controller Object</returns>  
  9.     public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)  
  10.     {  
  11.         Type controllerType = Type.GetType(string.Format("ControllersInDepth.Controllers.{0}", controllerName));  
  12.         //dynamically creating the object by using the Activator class  
  13.         IController tempController = Activator.CreateInstance(controllerType) as IController;  
  14.         return tempController;  
  15.     }  
  16.   
  17.     /// <summary>  
  18.    /// This function is used for maintaining the Controller SessionBehavior.  
  19.    /// </summary>  
  20.    /// <param name="requestContext"></param>  
  21.    /// <param name="controllerName"></param>  
  22.   /// <returns>SessionStateBehavior value</returns>            public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)  
  23. {  
  24.    return System.Web.SessionState.SessionStateBehavior.Default;  
  25. }  
  26.   
  27. /// <summary> 
    /// This function is used for releasing the controller object when not required.  
  28. /// </summary>  
  29. /// <param name="controller"></param>  
  30.    public void ReleaseController(IController controller)  
  31.    {  
  32.        IDisposable dispoable = controller as IDisposable;  
  33.        if (dispoable != null)  
  34.        dispoable.Dispose();  
  35.    } 

Once we are done with the creation of CustomControllerFactory we need to register it so that it be put to work. To register we need to add an entry inside the "Global.asax" file in Application_Start function. Here is the code snippet for the same.

  1. //registering the customControllerFactory  
  2. ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory()); 

Now we can start testing the application. For demonstrating this we’ve added a new model to the application with the name "ControllerDetails.cs" Here is the code snippet for the same.

  1. namespace ControllersInDepth.Models  
  2. {  
  3.     public class ControllerDetails  
  4.     {  
  5.        public string ControllerName { getset; }  
  6.     }  

Also we’ve created a new view in the shared folder with the name "Test.cshtml" and also added two controllers with the name “Home” and "Employee" on each index action method we are calling binding the Model "ControllerDetails" and calling the view "Test.cshtml".
Also in the RouteConfig.cs file we’ve added a new entry for the routing. Here is the code snippet.

  1. routes.MapRoute(  
  2. name: "customized",  
  3. url:"{controller}/{action}"  
  4. ); 

You can now start using the application. By simply running it. Here is the snapshot for the same.

running

Now just type /Employee/ in the address bar and hit enter. You’ll find that the controller name is now changed.
 
address bar