Retoques a MVC y Razor para proyectos grandes–Una recomendación

Luego de revisar los requerimientos de la aplicación en la que vengo trabajado estos últimos 6 meses,  tuve que pensar cómo plantear la arquitectura de la misma teniendo en cuenta lo siguiente:

  1. La aplicación es muy muy muy grande, eso era lo primero que saltaba a la vista en los requerimientos. Al día de hoy, esta cuenta con 1.119 vistas, 797 controladores y un número similar de modelos, entre otras cosas.
  2. El equipo iba a ser grande y la idea era que trabajaran lo más focalizados posible en sus casos de uso y luego integrarlos para evitar fricción de dependencias entre los diferentes casos de uso.
  3. La aplicación tiene módulos que agrupan sub-módulos y estos a su vez agrupan casos de uso. Los casos de uso eran bastante similares por lo que era también de esperarse que tuviesen una estructura similar entre ellos. Esto es: Vistas con idénticos o similares nombres como así también controladores y modelos similares los cuales podían también tener el mismo nombre.
  4. El esquema de seguridad se basa en perfiles de usuarios los cuales tienen permisos sobre distintas operaciones sobre cada uno de esos casos de uso.

Con eso en mente, era evidente que el esquema por defecto de MVC (usando Razor) no era el adecuado ya que, por defecto, este agrupa las vistas en la carpeta Views, controladores en la carpeta Controllers y modelos en la carpeta Models. Es muy difícil de trabajar en un sistema grande con esta estructura; es a todas luces insuficiente ya tener 1.119 vistas en una sola carpeta presenta muchos problemas no solo a la hora de encontrar un archivo sino que además obliga a que no existan dos vista con el mismo nombre y eso era algo que el proyecto necesitaba tener realmente.

De no plantear una estructura de módulos, sub-módulos y casos de uso adecuada a las necesidades del proyecto este iba a ser un desastre, así que así lo hice. Para esto extendí dos componentes: ControllerFactory y RazorViewEngine.

Antes de comenzar, y para que vayan dándose una idea, nuestro esquema de mapeo en el Global.asax es el siguiente:

image

Y nuestra estructura de carpetas es la que sigue:

image

El ControllerFactory (simplificado para este blog) se ve más o menos como figura abajo y nos permite tener clases controladores con el mismo nombre pero con distinto namespace:

image

Por otro lado, la organización de las vistas en carpetas módulo/sub-módulo/casodeuso/ se logró extendiendo la clase RazorViewEngine que es la encargada de resolver la ruta donde se deben buscar las vistas cuando desde un controllador se lo solicita. El código de la clase puede verse abajo:
image

Con esto no solo se logra que las vistas se busques en la carpeta propia del caso de uso al cual pertenecen sino que además el orden de búsqueda permite que si una vista, layout o template (EditorTemplate o DisplayTemplate) no se encuentra localmente en la carpeta del caso de uso, este busca luego en las vistas del sub-módulo y luego en las vistas del módulo.

 

Conclusión

Dado que ni el ControllerFactory del framework de MVC permite tener controladores con el mismo nombre ni que el esquema de carpetas que por defecto que utiliza RazorViewEngine es suficiente para proyectos realmente grandes, creo que todo proyecto necesita contemplar la conveniencia de, antes de comenzar a desarrollar sus casos de uso, estudiar esta o alguna otra alternativa.

Yo recomiendo esta solución fuertemente ya que viene dándonos excelentes resultados día tras día y nos ha vuelto la vida increíblemente más sencilla.

Sin categoría

2 thoughts on “Retoques a MVC y Razor para proyectos grandes–Una recomendación

  1. Esta bien tu aproximación, pero si es tan grande el proyecto, tambien te recomiendo qeu separes por proyectos tus modulos y luego los carges automagicamente con autofac (una especie de unity pero mejorado para aplicaciones web con sus extensiones).

    Tienes un ejemplo de implementación en el proyecto de código abierto NopCommerce. Ellos tienen en un proyecto separado el modulo de administración y se carga en el proyecto principal porque la dll está copiada a mano(como comando de post-compilation) dentro del bin del proyecto principal. En el global.asax, al cargar su infraestructura, es detectada por autofac y la carga.

    No estaría de más hacer eso ya que un proyecto con tantas clases me da a mi que no es muy manejable.

    Saludos.

Responder a rduarte Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *