¿Cómo estructurar múltiples soluciones / proyectos superpuestos en .Net?

16

Recientemente comencé a trabajar para un nuevo cliente con una antigua base de código heredada en la que hay múltiples soluciones .net, cada una de ellas típicamente alberga algunos proyectos únicos para esa solución, pero luego "toma prestados" / "enlaces" (agregue el proyecto existente) algunos otros proyectos que técnicamente pertenece a otras soluciones (al menos si vas por la estructura de carpetas en TFS)

Nunca he visto una configuración tan entrelazada, no hay un orden de compilación claro, a veces un proyecto en la solución A solo hace referencia a dlls directamente desde el directorio de salida de un proyecto alojado en la solución B, a veces el proyecto se ha incluido directamente incluso si reside LEJOS en la estructura de carpetas.

Parece que todo ha sido optimizado para la pereza del desarrollador.

Cuando me enfrenté a ellos por qué no tenían un servidor CI, respondieron que es difícil configurar el código organizado como está. (Lo estoy configurando ahora y maldijo esta organización de código)

Las soluciones están organizadas en torno a artefactos de implementación (las cosas que deben implementarse juntas se encuentran en la misma solución), lo que creo que es una decisión acertada, pero el contenido de esas soluciones (los proyectos) está por todas partes.

¿Existe un consenso de una mejor práctica para usar al reutilizar bibliotecas de clases comunes en múltiples soluciones / artefactos de implementación,

  • Cómo estructurar código en el VCS
  • Cómo facilitar el intercambio de lógica empresarial entre artefactos de implementación separados
AndreasKnudsen
fuente

Respuestas:

9

Nunca me ha gustado incluir proyectos existentes que pertenecen a otras soluciones. Hay demasiadas variables en las que realizar una edición de ese proyecto para 1 solución rompe completamente algo en otra solución. Luego, al solucionar ese problema, terminas rompiendo la solución original. Enjabonar, enjuagar, repetir.

Cuando este tipo de dependencia se filtra en múltiples soluciones, me gusta separar el código dependiente en su PROPIA solución y crear una biblioteca de recuadro negro que luego se incluye como referencia. Creo que sus soluciones se entrelazaron para que la depuración se pudiera realizar en todo el proyecto compartido para cada solución. Si la biblioteca está construida y probada correctamente, este tipo de depuración realmente no es necesaria. La biblioteca debe ser capaz de defender sus propios méritos y debe probarse a fondo para que las expectativas de cualquier proyecto del consumidor se cumplan de manera consistente.

Joel Etherton
fuente
3
Además, la refactorización es tan fácil en estos días, así que si haces la sensación de que algunos estímulo-de-la-momento de cambio es lo suficientemente importante como para que en la propia biblioteca, puede hacer que su proyecto de aplicación ahora y fusionarla en la biblioteca más tarde , cuando esté menos distraído por su tarea actual y tenga tiempo para realizar las pruebas adecuadas.
Aaronaught
@Aaronaught: +1 a eso.
Joel Etherton
5

De hecho, he organizado estructuras TFS como la que está mencionando y, aunque presenta desafíos únicos para CI, tiene varios beneficios diferentes. Una clara es que respalda y fomenta la adecuada componenteización en proyectos separados de .NET y, por lo tanto, admite una buena TDD al fomentar una cobertura de prueba del 100%. De buenas a primeras me doy cuenta de algunos problemas que puede abordar.

a veces un proyecto en la solución A solo hace referencia a dlls directamente desde el directorio de salida de un proyecto alojado en la solución B, a veces el proyecto se ha incluido directamente incluso si se encuentra LEJOS en la estructura de carpetas.

Las referencias binarias a la salida de otros directorios no son un buen enfoque, y también se convierten en un mal enfoque cuando se mezclan con referencias de proyectos. Trate de hacer una u otra, cambiando de preferencia las referencias binarias a referencias de proyecto por consistencia como mínimo. En este punto, cada Solución puede representar una sola aplicación o nivel de aplicación que se puede construir (por ejemplo, SuperApp.sln, OtherAppServices.sln, OtherAppPresentationTier.sln).

Para construir TODOS los proyectos, también recomiendo crear una solución maestra. La solución maestra tendrá referencias de proyectos a todo y esencialmente existe para el único beneficio de tener un solo comando de compilación que maneja todos los proyectos en el conjunto de aplicaciones. Los desarrolladores no deben usar la solución maestra para el desarrollo activo o la depuración. Esto facilita el montaje de los artefactos de construcción.

La implementación se puede hacer con un simple lote, powershell o script Perl. Esto esencialmente construirá la solución adecuada o la solución maestra y luego implementará todo en los entornos apropiados. Esto se puede integrar fácilmente en cualquier servidor de CI si se hace correctamente.

• Cómo facilitar el intercambio de lógica empresarial entre artefactos de implementación separados

Cree un proyecto para una lógica comercial común o tenga una mejor separación de preocupaciones para una lógica comercial más global o universal. Todas las soluciones implementables que deseen hacer referencia a esto deben hacerlo mediante una referencia de proyecto.

Al organizar su código en TFS, se hace más fácil lograr esto manteniendo los proyectos comunes o compartidos en un nivel superior en el árbol de directorios.

maple_shaft
fuente