2009-03-27 32 views
82

Tenemos una solución con más de 100 proyectos, la mayoría C#. Naturalmente, lleva mucho tiempo abrir y construir, por lo que estoy buscando las mejores prácticas para tales bestias. A lo largo de las líneas de preguntas Tengo la esperanza de obtener respuestas a, son:Mejores prácticas para soluciones grandes en Visual Studio (2008)

  • ¿Cómo te mejores referencias de la manija entre los proyectos
    • debería "copia local" ser encendido o apagado?
  • debería cada proyecto de construcción de su propia carpeta, o en caso de que toda la construcción en la misma carpeta de salida (todos ellos son parte de la misma aplicación)

  • son carpetas Solutions una buena manera de organizar ¿cosas?

sé que dividir la solución en múltiples soluciones más pequeñas es una opción, sino que viene con su propio conjunto de refactorización y la construcción de dolores de cabeza, así que tal vez puede ahorrar que por un hilo separado :-)

+2

¿Puedo preguntar por qué una sola solución necesita más de 100 proyectos? ¿Están creando cada uno su propia asamblea? –

+1

Sí, lo son, y cada uno de ellos representa una funcionalidad lógicamente separada. – Eyvind

+0

Tenemos algo similar aquí en Java ...un marco, alrededor de 200 complementos por ahora. Pone a Eclipse a prueba cuando los tengo cargados y apuesto a que no es tan raro (aunque esto es académico, probablemente diferente de The Real World ™). – Joey

Respuesta

4

Trabajamos en un proyecto grande similar aquí. Las carpetas de soluciones han demostrado ser una buena forma de organizar las cosas, y tendemos a simplemente dejar que el conjunto local de copias sea verdadero. Cada proyecto se construye en su propia carpeta, y luego sabemos que para cada proyecto desplegable allí tenemos el subconjunto correcto de los binarios en su lugar.

En cuanto a la apertura del tiempo y la creación de tiempo, va a ser difícil de solucionar sin entrar en soluciones más pequeñas. Podría investigar la paralelización de la compilación (google "Parallel MS Build" para una forma de hacerlo e integrarla en la interfaz de usuario) para mejorar la velocidad aquí. Además, fíjese en el diseño y vea si la refacturación de algunos de sus proyectos para reducir el total podría ayudar.

3

En términos de aliviar el problema del edificio, puede usar la opción "Administrador de configuración ..." para compilaciones para habilitar o deshabilitar la construcción de proyectos específicos. Puede tener un "proyecto [n] compilación" que podría excluir ciertos proyectos y utilizarlo cuando esté orientando proyectos específicos.

En lo que respecta a los más de 100 proyectos, sé que no quiere que se le aclare esta pregunta sobre los beneficios de reducir el tamaño de su solución, pero creo que no tiene otra opción cuando se trata de acelerar tiempo de carga (y uso de memoria) devenv.

+0

Hm, ¿esta votación fue negativa por estar equivocada, o simplemente por estar en desacuerdo? Puedo vivir con el primero si puedes decirme por qué. –

+0

Estoy de acuerdo, me desagrada votar sin comentarios, por lo que Michael obtienes mi +1 para equilibrar la ecuación ;-) – si618

+2

por cierto, personalmente no me gusta perder el tiempo con la gestión de configuración para este tipo de cosas. ¿Por qué? porque si accidentalmente compromete su configuración modificada, su servidor de compilación u otros desarrolladores se verán afectados. – si618

9

+1 para ahorrando uso de carpetas de soluciones para ayudar a organizar cosas.

+1 para la construcción de proyectos en su propia carpeta. Inicialmente probamos una carpeta de salida común y esto puede llevar a sutiles y dolorosas a encontrar referencias desactualizadas.

FWIW, usamos referencias de proyectos para soluciones, y aunque nuget es probablemente una mejor opción en estos días, he encontrado que svn: externals funciona bien para ensamblajes internos de terceros y (tipo de marco). Simplemente hágase el hábito de usar un número de revisión específico en lugar de HEAD cuando haga referencia a svn: externals (culpable como se cobra :)

+2

+1 También tengo problemas con la solución de carpeta de salida común. No entendí lo que significa "referencias de proyectos para soluciones", explique un poco más ... –

+0

Al igual que en VS-> Agregar referencia-> Proyectos, en lugar de VS-> Agregar referencia-> Buscar. Pequeño punto que sé, pero algunas personas lo hacen de manera diferente (y creo que esto causa más dolores de cabeza). Si observa el texto de MSBuild csproj, verá la propiedad ProjectReference en lugar de Reference. – si618

+0

¡Respuesta interesante! Creo que zigzagueamos donde te zagaste. No tenemos carpetas de soluciones en absoluto y confiamos en la denominación de proyectos (los proyectos reciben el mismo nombre que el espacio de nombres). Toda nuestra salida va a una sola carpeta, lo que hace que la configuración del desarrollador esté mucho más cerca de la implementación. Si las dependencias están configuradas correctamente, entonces no tenemos referencias desactualizadas. –

3

Lo que normalmente hago con esto depende un poco de cómo realmente ocurre el proceso de "depuración". Por lo general, aunque NO configuro la copia local para que sea verdadera. Configuré el directorio de compilación para cada proyecto para producir todo en el punto final deseado.

Por lo tanto, después de cada compilación tengo una carpeta llena con todas las DLL y cualquier aplicación de Windows/web y todos los elementos están en la ubicación correcta. No se necesitó copiar local ya que el dll termina en el lugar correcto al final.

Nota

Los trabajos anteriores para mis soluciones, que normalmente son aplicaciones web y no he tenido ningún problema con las referencias, pero podría ser posible!

3

Tenemos un problema similar. Lo resolvemos usando soluciones más pequeñas. Tenemos una solución maestra que abre todo. Pero perf. en eso es malo. Por lo tanto, segmentamos soluciones más pequeñas por tipo de desarrollador. Por lo tanto, los desarrolladores de DB tienen la misma solución que los proyectos que les importan, los desarrolladores de servicios y los desarrolladores de UI. Es raro cuando alguien tiene que abrir toda la solución para obtener lo que necesitan hacer día a día. No es una panacea, tiene sus ventajas y desventajas. Consulte "modelo de soluciones múltiples" in this article (ignore la parte sobre el uso de VSS :)

6

Tenemos un problema similar ya que tenemos 109 proyectos diferentes para tratar. Para responder a las preguntas originales, basadas en nuestras experiencias:

1. ¿Cómo hacer que las mejores referencias de la manija entre los proyectos

Usamos la opción del menú contextual 'añadir referencia'. Si se selecciona 'proyecto', entonces la dependencia se agrega a nuestro único archivo de solución global de manera predeterminada.

2. ¿Se debe activar o desactivar "copiar local"?

Apagado en nuestra experiencia. La copia adicional solo aumenta los tiempos de compilación.

3. En caso de que todos los proyectos de construcción a su propia carpeta, o en caso de que toda la construcción en la misma carpeta de salida (todos ellos son parte de la misma aplicación)

Toda nuestra salida se colocan en una sola carpeta llamada 'bin'. La idea es que esta carpeta sea la misma que cuando se implementa el software. Esto ayuda a prevenir problemas que ocurren cuando la configuración del desarrollador es diferente de la configuración de implementación.

4. ¿Las carpetas de soluciones son una buena forma de organizar cosas?

No en nuestra experiencia. La estructura de carpetas de una persona es la pesadilla de otra persona. Las carpetas profundamente anidadas solo aumentan el tiempo que lleva encontrar algo. Tenemos una estructura completamente plana, pero el nombre de nuestros archivos de proyectos, ensambles y espacios de nombres es el mismo.


Nuestra manera de estructurar proyectos se basa en un único archivo de solución. Construir esto lleva mucho tiempo, incluso si los proyectos en sí mismos no han cambiado. Para ayudar con esto, normalmente creamos otro archivo de solución de "conjunto de trabajo actual". Cualquier proyecto en el que estamos trabajando se agrega a esto. Los tiempos de compilación han mejorado mucho, aunque un problema que hemos visto es que Intellisense falla para tipos definidos en proyectos que no están en el conjunto actual.

un ejemplo parcial de nuestra solución de diseño:

\bin 

OurStuff.SLN 

OurStuff.App.Administrator 
OurStuff.App.Common 
OurStuff.App.Installer.Database 
OurStuff.App.MediaPlayer 
OurStuff.App.Operator 
OurStuff.App.Service.Gateway 
OurStuff.App.Service.CollectionStation 
OurStuff.App.ServiceLocalLauncher 
OurStuff.App.StackTester 
OurStuff.Auditing 
OurStuff.Data 
OurStuff.Database 
OurStuff.Database.Constants 
OurStuff.Database.ObjectModel 
OurStuff.Device 
OurStuff.Device.Messaging 
OurStuff.Diagnostics 
... 
[etc] 
+0

¿Podría "compilar en una carpeta de salida" causar problemas al compilar con múltiples subprocesos? – BrunoLM

2

creo que con las soluciones de esta amplia la mejor práctica se debe a separarlos. Puede pensar en la "solución" como un lugar para reunir los proyectos necesarios y tal vez otras piezas para trabajar en una solución a un problema. Al dividir los más de 100 proyectos en múltiples soluciones especializadas para desarrollar soluciones para solo una parte del problema general, puede tratar menos en un determinado momento acelerando sus interacciones con los proyectos requeridos y simplificando el dominio del problema.

Cada solución produciría la salida de la cual es responsable. Esta salida debe tener información de versión que se puede establecer en un proceso automatizado. Cuando el resultado es estable, puede actualizar las referencias en proyectos y soluciones dependientes con la distribución interna más reciente. Si aún desea ingresar al código y acceder a la fuente, puede hacerlo con el servidor de símbolos de Microsoft que Visual Studio puede usar para permitirle ingresar a los ensambles a los que hace referencia e incluso buscar el código fuente.

El desarrollo simultáneo se puede realizar especificando interfaces por adelantado y burlándose de los ensamblados en desarrollo mientras espera dependencias que no están completas pero que desea desarrollar en contra.

Considero que esta es una buena práctica porque no hay límite para lo complejo que puede ser el esfuerzo general cuando se descompone físicamente de esta manera. Poner todos los proyectos en una sola solución eventualmente llegará a un límite superior.

Espero que les haya sido útil esta información.

2

Tenemos más de 60 proyectos y no usamos archivos de soluciones. Tenemos una mezcla de proyectos C# y VB.Net. El rendimiento siempre fue un problema. No trabajamos en todos los proyectos al mismo tiempo. Cada desarrollador crea sus propios archivos de solución en función de los proyectos en los que están trabajando. Los archivos de la solución no se verifican en nuestro control de origen.

Todos los proyectos de la biblioteca de clase construirían en una carpeta CommonBin en la raíz del directorio de origen. Proyectos ejecutables/Web construidos en su carpeta individual.

No utilizamos referencias de proyecto, en cambio, referencia basada en archivos de la carpeta CommonBin. Escribí una tarea personalizada de MSBuild que inspeccionaría los proyectos y determinaría el orden de compilación.

Hemos estado utilizando esto desde hace algunos años y no tenemos ninguna queja.

+3

¿Te importaría compartir tu tarea personalizada de msbuild? – andreapier

40

Puede que le interesen estos dos artículos de MSBuild que he escrito.

MSBuild: Best Practices For Creating Reliable Builds, Part 1

MSBuild: Best Practices For Creating Reliable Builds, Part 2

modo específico en la parte 2 hay una sección La construcción de grandes árboles de origen que es posible que desee echar un vistazo a.

Para responder brevemente a sus preguntas aquí, sin embargo:

  • CopyLocal? Desactive esta opción
  • ¿Cree en una o varias carpetas de salida? Crear en una carpeta de salida
  • ¿Carpetas de soluciones? Esto es una cuestión de gusto.

Sayed Ibrahim Hashimi

Mi libro: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

+0

Gracias, hombre, ¡me aseguraré de verificarlos! – Eyvind

+1

Diré que tengo este libro y es increíble. Me ha ayudado a automatizar mis compilaciones TFS y las compilaciones de desarrollo local de forma muy extensa. Ahora estoy trabajando en compilaciones incrementales, y el libro profundiza en el tema. Vale el precio. Gracias Sayed. Mantener el buen trabajo. – irperez

+0

Gracias irperez por los comentarios –

8

proyectos Unload que no utiliza con frecuencia, y comprar un SSD. Un SSD no mejora el tiempo de compilación, pero Visual Studio se vuelve dos veces más rápido para abrir/cerrar/compilar.

+3

Vale la pena señalar que la descarga de un proyecto es una configuración por usuario, por lo que los desarrolladores en su equipo solo puede cargar los proyectos que les importan. Esto realmente ha ayudado a nuestro equipo. –

+0

Puede usar la extensión del Administrador de carga de la solución http://visualstudiogallery.msdn.microsoft.com/66350dbe-ed01-4120-bea2-5564eff7b0b2 para definir qué no cargar por defecto –

0

Todo tiene que ver con su definición y visión de lo que son una solución y un proyecto. En mi opinión, una solución es solo eso, una agrupación lógica de proyectos que resuelve un requisito muy específico. Desarrollamos una gran aplicación de Intranet. Cada aplicación dentro de esa Intranet tiene su propia solución, que también puede contener proyectos para servicios antiguos o de Windows. Y luego tenemos un marco centralizado con cosas como clases base y ayudantes y httphandlers/httpmodules. El marco base es bastante grande y lo utilizan todas las aplicaciones. Al dividir las muchas soluciones de esta forma, se reduce la cantidad de proyectos requeridos por una solución, ya que la mayoría de ellos no tienen nada que ver entre sí.

Tener tantos proyectos en una solución es simplemente un mal diseño. No debería haber ninguna razón para tener tantos proyectos bajo una solución. El otro problema que veo es con referencias de proyectos, que realmente pueden arruinarlo eventualmente, especialmente si alguna vez quiere dividir su solución en otras más pequeñas.

Mi consejo es hacer esto y desarrollar un marco centralizado (su propia implementación de Enterprise Library si lo desea). Puede GAC compartirlo o puede hacer referencia directamente a la ubicación del archivo para que tenga una tienda central. También podría usar la misma táctica para objetos comerciales centralizados.

Si desea hacer referencia directa a la DLL, querrá hacer referencia a ella en su proyecto con copy local false (en algún lugar como c: \ mycompany \ bin \ mycompany.dll). En tiempo de ejecución, deberá agregar algunas configuraciones a su app.config o web.config para que haga referencia a un archivo que no está en el GAC o en el contenedor de tiempo de ejecución. En realidad, no importa si se trata de una copia local o no, o si el dll termina en el contenedor o incluso en el GAC, porque la configuración anulará ambas. Creo que es una mala práctica copiar local y tener un sistema desordenado. Lo más probable es que tenga que copiar local temporalmente si necesita depurar en uno de esos ensamblajes.

Puede leer mi artículo sobre cómo usar una DLL globalmente sin GAC. Realmente no me gusta el GAC porque evita la implementación de xcopy y no activa un autortart en las aplicaciones.

http://nbaked.wordpress.com/2010/03/28/gac-alternative/

0

Conjunto CopyLocal = false reducirá el tiempo de construcción, pero puede causar problemas diferentes durante el tiempo de implementación.

Hay muchos escenarios, cuando debe tener Copy Local 'left to True, p. Proyectos de nivel superior, Dependencias de segundo nivel, DLL llamadas por reflexión.

Mi experiencia con la configuración CopyLocal = false no fue exitosa. Ver resumen de pro y contra en mi entrada de blog "Do NOT Change "Copy Local” project references to false, unless understand subsequences."

Cuestiones relacionadas