ASP.NET MVC Framework has been around for quite sometime now.It has now moved to BETA from it's initial CTP versions.I am a very big fan of this framework for it's simplicity and extensibility.For the next few posts I would like discuss about the various extensibility points of this framework.In this post I will note down my observations about implementing a custom controller factory.
When adding a controller to a ASP.NET MVC Web application we see that the Controller name must end with "Controller" and it is recommended that Controller classes to be put inside a subfolder named "Controllers" in the web application directory.Now think of a situation where I have many controller classes and for better maintainability I need to put them into separate assemblies.In addition to that I need to load the controller classes in a configurable manner based on controller name in the URI.
This can be done by implementing a custom controller factory to instantiate the right controller class based on config settings.To do this we need to implement the interface System.Web.Mvc.IControllerFactory .The two methods in this interface are
- System.Web.Mvc.IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) - To create the controller instance based on RequestContext and controller name
- void ReleaseController(System.Web.Mvc.IController controller) - Release the controller instance
Following is the sample code with very rudimentary implementation:
public class CustomControllerFactory : IControllerFactory
{
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
string controllerType = string.Empty;
IController controller = null;
//Read Controller Class & Assembly Name from Web.Config
controllerType = ConfigurationManager.AppSettings[controllerName];
if (controllerType == null) throw new ConfigurationErrorsException("Assembly not configured for controller " + controllerName);
//Create Controller Instance
controller = Activator.CreateInstance(Type.GetType(controllerType)) as IController;
return controller;
}
public void ReleaseController(IController controller)
{
//This is a sample implementation
//If pooling is used write code to return the object to pool
if (controller is IDisposable)
{
(controller as IDisposable).Dispose();
}
controller = null;
}
}
Now the question comes how do we integrate this ControllerFactory with the application.This can be done by setting the Controller factory using System.Web.Mvc.ControllerBuilder in Application_Start event of Global.asax.cs
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(typeof(SB.Web.Mvc.CustomControllerFactory));
}
Lastly we need to add the config entries for the Controller classes and assemblies in Web.config as shown below:
<appSettings>
<add key="Home" value="SB.Controllers.HomeController, SB.Controllers"/>
</appSettings>
We can enhance this further by adding features like pooling,instancing mode (Singleton) etc.
In my next post I will discuss about my observations about the extension points related to Views.