Estrategia de Organización de Código Fuente
Recomendaciones de un experto de Microsoft NY
La compilación de la solución actualmente toma demasiado tiempo debido a la gran cantidad de proyectos en la solución. Esto también causa mucha complejidad cuando intentamos administrar las dependencias como los paquetes Nuget y cuando queremos hacer limpieza del código haciendo "refactoring". Ofrezco las siguientes recomendaciones para consolidar proyectos:
- Consolidar proyectos basándonos principalmente en unidades de instalación, por esto me refiero a esos componentes que se instalan por si solos como:
- Webs (interfaces de usuarios)
- APIs (interfaces con máquinas)
- Servicios Asíncronos
- Luego, consolidar los proyectos según se necesiten compartir entre las unidades de instalación.
- Por lo general no hay problema con tener solo un proyecto “DLL” que incluye todo el DAL y BL.
- Puede que esto no sea posible en ciertos casos que se desea inyectar funcionalidad a la aplicación sin tener que recompilar todo, si este es el caso pues se permite tener una separación de DLLs mas estratégica. Pero aun así, rara la vez se necesitan más de unos 15 a 20 proyectos hasta para las soluciones más complejas.
- Añadir un nuevo proyecto no debe ser una decisión ligera y debe ser discutida con el equipo.
- Similarmente, añadir un paquete Nuget o implementar un nuevo patrón de arquitectura no se debe hacer en aislamiento y debe ser discutido por el equipo.
Bases de datos
Uso de Entity Framework (EF)
- Se recomienda el uso de EF para la mayoría de los casos de acceso a la base de datos, código que aun usa ADO.NET sin buena razón debe ser actualizado a EF.
- Consolidar uso de migraciones de EF o proyectos SSDT (SQL Server Data Tools) (Decidir si usar uno u otro).
- Las bases de datos tienen que ser mantenidas en código fuente y los cambios a las bases de datos de producción solo deben venir de un build que haya pasado todas las pruebas unitarias. Cualquier “hot fix” a la base de datos tiene que ser consolidado de inmediato al código fuente.
Estrategia de Pruebas Unitarias
- Las pruebas unitarias deben correr sin problemas para un nuevo desarrollador que acaba de recibir la solución desde codigo fuente sin ningún tipo de configuración manual, o sea, la ejecución de la prueba unitaria se hace cargo de configurar automáticamente todas las dependencias y de limpiar el ambiente en caso de que una prueba falle.
- Debemos configurar tantas pruebas unitarias como sea posible para que corran con el build diario. Esto envuelve implementar muy bien el punto anterior de la configuración automatizada.
- Se recomienda usar la estrategia “fail fast” con un mensaje de error claro donde evitamos tragarnos las excepciones y en vez las reportamos tan pronto es posible.
Estrategia para "Refactoring"
Hay que sacar tiempo en todas las iteraciones de desarrollo para hacer “refactoring” para limpiar el código y mejorar la lectura y comprensión del mismo. Recomiendo que los desarrolladores saquen un 10% de su tiempo para esto. Nunca combinen tareas de “refactoring” con tareas de nueva implementación. Todo “refactoring” debe hacerse con el apoyo de pruebas unitarias que nos dirán si el “refactoring” ha roto la aplicación.
Una guía que recomiendo para hacer “refactoring” es repite el mismo código hasta dos veces, a la tercera no lo repitas más y haz “refactoring” para reusar el mismo codigo. Si seguimos esta simple guía nuestro código ira mejorando mucho. Recuerden, si estamos haciendo mucho “copy/paste” lo más seguro necesitamos hacer “refactoring” en vez.
Estrategia DevOps
Una vez tenemos un build estable y pruebas unitarias confiables podemos comenzar a configurar el empaque de la solucion y la transferencia a los otros ambientes como QA y Producción.
Para esto recomiendo usar la funcionalidad de “Releases” de VSTS que podemos usar para automatizar la creación de paquetes de instalación o hasta automatizar completamente la instalación a los ambientes QA y hasta PROD.