En nuestro trabajo, tenemos varias aplicaciones .net diferentes que comparten muchas funciones básicas. Creamos estas aplicaciones utilizando una arquitectura limpia de n niveles, pero llegamos a ese momento en el que nos damos cuenta de que hemos vuelto a implementar las mismas funciones varias veces. Obviamente, esto viola DRY, y nos gustaría corregir eso. Ya estamos usando Nuget con cierto éxito para el código de pegamento común (cableado de IoC, registro, configuración), pero también nos gustaría compartir nuestros datos y capas comerciales entre todas nuestras aplicaciones. La idea es que la interfaz de usuario solo se ocupe de las partes de la capa empresarial que realmente necesita.
Esto parece un problema directo al principio, pero el desarrollo continuo podría proporcionar algunas dificultades y no estamos seguros de cómo proceder. Supongamos que creamos nuestra capa empresarial única para gobernarlos a todos. Por brevedad, lo llamaré "Fundación". Portamos nuestras aplicaciones para usar la Fundación, y todo funciona muy bien. La Fundación se distribuye a capas de interfaz de usuario ligeras a través de nuget, y nos vemos bien. Pero luego comenzamos a agregar funciones a nuestras aplicaciones y nos encontramos con problemas.
Digamos que estamos trabajando en el Proyecto A y agregamos una nueva característica que requiere cambios en Foundation. Realizamos los cambios en la base (Foundation-A) y los enviamos al feed nuget como un paquete inestable. El Proyecto A obtiene el último paquete Nuget, y todo está bien. Mientras tanto, otro desarrollador está trabajando en el Proyecto B. Obtiene la última Fundación del control de código fuente, pero la toma de una rama estable, para que no tenga cambios en el Proyecto A. Él hace cambios y creó la Fundación B. Y todo esta bien. Pero luego descubrimos que la funcionalidad de implementación de Foundation-A y Foundation-B podría compartir código, por lo que las combinamos. Mientras tanto, Foundation-C está flotando por ahí con sus propios cambios. Finalmente, Foundation-B está lista para la producción, por lo que la sacamos. Pero luego necesitamos actualizar la producción A, B,
Parece que podría funcionar, pero nos preocupa trabajar con diferentes esquemas de bases de datos y mantener todo sincronizado entre las diversas ramas del repositorio de Foundation y los repositorios del Proyecto A, B y C. Parece que probablemente tomará mucho trabajo manual, lo que abre la posibilidad de errores. Me gustaría que esto sea lo más automatizado posible.
Aquí está la pila que estamos usando: C #, TFS con integración continua, Nuget. Nuestras aplicaciones son todos los diversos tipos de aplicaciones ASP.NET. Estamos dispuestos a ver diferentes SCM si eso facilitará las cosas.
Estoy buscando formas de mantener a Nuget cuerdo con nuestras diferentes ramas de código fuente. No queremos introducir accidentalmente el código de desarrollo en producción porque hacemos referencia al paquete Nuget incorrecto.
Respuestas:
Aquí es donde comienza tu problema ... No hagas eso.
Cualquier cambio en Foundation v1.0 debería ser inherentemente valioso para todos los consumidores de Foundation, de lo contrario no pertenece a Foundation. Entonces, al crear el paquete nuget, hágalo como una versión oficial y estable de Foundation (es decir, v1.1), o no lo haga en absoluto.
El Proyecto B debería construir sus mejoras de la Fundación como lo haría normalmente, pero (en una buena gestión de la fuente) debería fusionarse en los cambios troncales (v1.1) antes de empujar una Fundación estable (v1.2) para nuget.
Otros proyectos que pueden usar las mejoras de Foundation pueden actualizar sus referencias nuget cuando sea apropiado, o seguir con las versiones anteriores si es necesario.
Estoy de acuerdo con @Giedrius ; Esto me parece más un problema de control de origen / ramificación en el sentido de que si la ramificación / fusión de Foundation se maneja correctamente, los problemas de gestión de paquetes se vuelven discutibles.
fuente
Refactorice su código duplicado en funciones que sean aplicables de una manera más abstracta y colóquelas en sus propias bibliotecas o marcos. Hágalos sin apretar y sin arquitectura, y nunca debería tener ningún problema. Si necesita inspiración, estudie cómo el marco .NET abstrae conceptos usando cosas como interfaces, genéricos y patrones de software como
Dispose()
.Además, recuerde que no todo el código duplicado está realmente duplicado; parte de esto es código de pegamento o código que de otro modo es necesario para mantener la arquitectura, así que no te obsesiones con estar demasiado SECO.
fuente
Reutilización de código
Ha habido varios enfoques para la reutilización de código que han encontrado favor a lo largo de los años. Cada enfoque tiene su lugar y, lo que es más importante, sus problemas , pero las formas viables de reutilizar el código en .NET son:
Biblioteca Común. El código que se necesita en más de un lugar se coloca en una biblioteca común, y todas las demás partes de la base del código tienen una sola referencia a este código. La desventaja principal es que terminas con la mayoría de tu proyecto dependiendo de esta biblioteca que contiene muchas funciones no relacionadas. Esta es una mala idea desde un aspecto de garantía de calidad.
Código fuente común. El código que se necesita en más de un lugar se escribe una vez y se coloca en un archivo fuente en una estructura de directorio común. Todos los proyectos que necesitan este código incluyen este archivo como uno de sus archivos fuente. Esto proporciona la reutilización del código, y las ventajas de escribir una vez, usan muchas. Sin embargo. Su desventaja es que es posible tener diferentes partes del proyecto compiladas con diferentes versiones de este código, lo que puede introducir algunos defectos sutiles que pueden ser muy difíciles de detectar e identificar mediante el aseguramiento de la calidad.
Servicio. El código común se implementa como un servicio al que pueden acceder otros aspectos. Esto tiene la ventaja de que habrá un único servicio en una implementación y evita las dependencias. Sin embargo, introducirá latencia y fallas. Este tipo de enfoque funciona bien en productos distribuidos grandes donde la alta disponibilidad y la tolerancia a fallas ya se comprenden y administran.
Administrar NuGET
Aquí tienes un problema mucho más interesante. Gestión de múltiples configuraciones. Mi consejo aquí es no administrar una base de clientes diversa con diferentes versiones de código, sino con archivos de configuración. Hay al menos 3 capas de datos de configuración para administrar. Configuración básica (interna) del producto que el cliente nunca ve. Las opciones de configuración predeterminadas que su cliente puede cambiar y la capa final de opciones de configuración que su cliente ha cambiado. Al separar estas diferentes capas, podrá implementar actualizaciones sin destruir las configuraciones de sus clientes.
fuente
Creo que el problema no está en nuget / control de origen / ramificación, sino en lo que se desliza en el código de pegado.
Robert tiene una buena respuesta, solo para ver la imagen completa, recomiendo pensar en las dependencias que estas utilidades comunes traerán a cada proyecto:
http://ayende.com/blog/3986/let-us-burn-all-those-pesky-util-common-libraries http://blog.jordanterrell.com/post/CommonUtility-Libraries-Dead.aspx
La mejor manera de evitar el infierno que tienes es abrir el código de pegamento. De tal manera que comenzará a preocuparse, que ninguna lógica de negocios se haga pública, por lo que ninguna dependencia concreta del proyecto se deslizará en el código de pegamento, que sería lo suficientemente abstracto como para ser reutilizado por cualquier persona, incluso fuera de su empresa, y si eso pega el código será lo suficientemente bueno, también obtendrá información de la comunidad
fuente
La solución es simple: cree un proyecto separado para él y adminístrelo como algo separado: sus propios requisitos, pruebas, convenciones, documentación, planificación, personas, etc. De esta manera, se asegura de que la calidad siga siendo alta y que se produzcan posibles cambios importantes. evaluado primero antes de que creen un problema.
O incluso mejor: hágalo "código abierto" dentro de su organización. Por lo tanto, cualquiera puede cambiar el código, pero solo unas pocas personas seleccionadas tendrán derechos de confirmación completos. Y esas personas serán responsables de garantizar la calidad y las características correctas.
fuente