This is something I toyed with a couple of months ago as a proof of concept. I hope that some aspect of this feature makes its way into the core of ASP.NET MVC. It rose from experimenting with some ideas for data driven portable areas, and wanting to leverage an IoC container of my own choosing (independent of the consuming application). I wanted to prove that this was possible in ASP.NET MVC 2. The code for this lives in an MvcContrib fork.
The idea is simple: a new factory called AreaControllerFactory. It inherits from DefaultControllerFactory, which remains the fallback means of producing a Controller.
public class AreaControllerFactory : DefaultControllerFactory
{
private IControllerFactoryRegistry _registry;
public AreaControllerFactory(IControllerFactoryRegistry registry)
{
_registry = registry;
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
string areaName = ((Route)requestContext.RouteData.Route).DataTokens["area"] as string;
IControllerFactory factory = _registry.FactoryFor(areaName);
if (factory == null)
return base.CreateController(requestContext, controllerName);
return factory.CreateController(requestContext, controllerName);
}
}
The AreaControllerFactory depends on an IControllerFactoryRegistry object to manage the controller factories. The FactoryFor() method returns a ControllerFactory that has been registered for a specific area using RouteData.
The IControllerFactoryRegistry interface looks like this:
public interface IControllerFactoryRegistry
{
void Register(string areaName, IControllerFactory factory);
void Default(IControllerFactory factory);
IControllerFactory FactoryFor(string areaName);
}
I have created a default implementation of this interface that uses a simple dictionary internally. That code isn’t particularly interesting. Up to now this is pretty intuitive, but I think the real slick part is how everything comes together with the ControllerFactoryRegistrar class. It is a singleton wrapper for an IControllerFactoryRegistry object.
Right now, the Area Controller Factories get set up by calling ControllerFactoryRegistrar.BootStrap(). It takes the current ControllerFactory and uses it as a default option. Then, it builds up a registry for all of the PortableAreas in the AppDomain. A new AreaControllerFactory is created with the registry, and set as the new ControllerFactory. Now, the creation of a controller will depend on what area it belongs to.
Non-portable areas can be registered with individual controller factories as well. Just call ControllerFactoryRegistrar.Register(areaName, factory).
All of this currently fits into MVC 2. With Area Controller Factories, Portable Areas have a new option for managing dependencies within its controllers.