vendredi 16 octobre 2009

ASP.NET MVC : changer de ControllerFactory

Le framework ASP.NET MVC utilise ce qu’on appelle “convention over configuration”, ce qui signifie qu’on n’a pas besoin de configurer manuellement notre application pour avoir une application qui fonctionne, tant que l’on respecte certaines conventions. Si l’on ne souhaite pas utiliser ces conventions, on a toujours la possibilité de configurer l’application pour travailler autrement.

En pratique, qu’est-ce que ça signifie ?

Lorsque l’on crée un nouveau projet MVC, les contrôleurs sont disposés dans le dossier « Controllers » de l’application, et leur nom doit forcément se terminer par « Controller ». Si on crée un contrôleur dans un autre namespace, ou si son nom est incorrect, le contrôleur ne sera pas reconnu par MVC. Pour pouvoir changer cette convention, on a la possibilité de créer notre propre ControllerFactory, dans lequel on pourra définir nos règles d’appel de nos contrôleurs.

Pour créer un ControllerFactory, il va falloir créer une nouvelle classe qui implémentera l’interface IControllerFactory, contenant 2 méthodes :

IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
et
void ReleaseController(IController controller)

La première va nous permettre de renvoyer une instance d’un contrôleur en fonction de son nom, et éventuellement de paramètres venant de la requête ; la seconde va nous permettre de libérer un contrôleur qui n’est plus utilisé. Le résultat ressemblera à quelque chose comme ça :

    public class CustomControllerFactory : IControllerFactory
    {

       
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
           
if (string.IsNullOrEmpty(controllerName))
               
throw new ArgumentNullException("Controller name can't be empty");

           
String controllerType = String.Concat("MyMvcApplication.CustomController.", controllerName);

           
IController controller = Activator.CreateInstance(Type.GetType(controllerType)) as IController;

           
return controller;
        }

       
public void ReleaseController(IController controller)
        {
           
IDisposable disposableController = controller as IDisposable;
           
if (disposableController != null)
                disposableController.Dispose();
        }

    }

Une fois notre classe créée, il faut l’enregistrer pour qu’elle soit utilisée à la place de la Factory par défaut. Pour ça, on a une méthode SetControllerFactory qu’il nous faut appeler au démarrage de l’application, dans le global.asax :

    protected void Application_Start()
    {
        RegisterRoutes(
RouteTable.Routes);

       
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
    }

Une fois ceci fait, nos anciens contrôleurs ne sont plus appelés, la recherche se fera dans le namespace MyMvcApplication.CustomController comme cela a été défini dans notre CustomControllerFactory.

Crossposté vers Tech Head Brothers