2010-01-20 21 views
6

Como prefacio, he estado trabajando con C# durante algunos meses, pero no estoy familiarizado con conceptos como implementación y ensamblajes, etc. Mis preguntas son muchas y variadas, aunque busco en Google y leo sobre ellas. en vano (actualmente tengo Pro C# 2008 y la plataforma .NET 3.5 frente a mí).¿Cómo trabajo con conjuntos y proyectos compartidos?

Tenemos este proceso y se compone de tres componentes: un motor, un filtro y lógica para el proceso. Nos encanta tanto este proceso que queremos que se reutilice en otros proyectos. Así que ahora estoy empezando a explorar el espacio más allá de una solución, un proyecto.

¿Esto suena correcto? Una gran Solución:

  • Proceso A, exe
  • Proceso B, exe
  • proceso C, exe
  • filtro, DLL
  • motor, DLL

El motor es compartida código para todos los procesos, entonces supongo que puede ser un ensamblado compartido? Si un conjunto compartido está en la misma solución que un proyecto que lo consume, ¿cómo se consume si se supone que está en el GAC? He leído algo sobre un evento de compilación posterior. ¿Eso significa que engine.dll tiene que ser reployed en cada compilación?

Además, la razón principal por la que separó el filtro del proceso (solo un proceso lo usa) es para que podamos implementar el filtro independientemente del proceso para que el proceso ejecutable no necesite ser actualizado. Independientemente de si esa es la mejor práctica, simplemente sigamos con esto. es posible? He leído que los ensamblajes enlazan con versiones específicas de otros ensamblajes, por lo que si actualizo solo el archivo DLL, en realidad se considera una alteración. ¿Cómo puedo actualizar la DLL sin cambiar el EXE? ¿Para eso sirve una política de editor?

Por cierto, ¿es esto posible Google-able o Amazon-able? ¿Que debería buscar? Veo muchos libros sobre C# y .NET, pero ninguno sobre implementación, construcción o pruebas o cosas que no están relacionadas con el lenguaje en sí.

+0

un buen libro que describe exactamente qué archivos, ensamblajes y módulos son es CLR a través de C# por Jeffrey Richter. En mi humilde opinión, este libro es irremplazable como fuente para aprender los fundamentos de .NET –

Respuesta

3

Estoy de acuerdo con el análisis de Aequitarum. Solo un par de puntos adicionales:

El motor es código compartido para todos los procesos, entonces supongo que puede ser un ensamblado compartido.

Eso parece razonable.

Si un conjunto compartido está en la misma solución que un proyecto que lo consume, ¿cómo se consume si se supone que está en el GAC?

Magic.

OK, no es mágico. Supongamos que en su solución su proceso proyecto tiene una referencia al motor proyecto. Cuando construya la solución, producirá un proyecto ensamblado que tiene una referencia al ensamblaje del motor . Visual Studio luego copia los diversos archivos en los directorios correctos. Cuando ejecuta el ensamblado de proceso, el cargador de tiempo de ejecución sabe buscar en el directorio actual para el ensamblaje del motor. Si no puede encontrarlo allí, se ve en el caché de ensamblaje global. (Esta es una vista muy simplificada de la política de carga, la política real es considerablemente más compleja que eso.)

Las cosas en el GAC deben ser verdaderamente global código; código que razonablemente espera que use un gran número de proyectos dispares.

¿Eso significa que engine.dll tiene que ser reployed en cada compilación?

No estoy seguro de lo que quiere decir con "redeployed". Como dije, si tiene una referencia de proyecto a proyecto, el sistema de compilación copiará automáticamente los archivos en los lugares correctos.

la razón principal que nos separamos el filtro del proceso (sólo un proceso que utiliza) es por lo que podemos desplegar el filtro independientemente del proceso para que el proceso ejecutable no necesita ser actualizado

Me pregunto si eso es realmente valioso. Escenario uno: sin ensamblaje de filtro, todo el código de filtro está en project.exe. Desea actualizar el código de filtro; usted actualiza project.exe. Escenario dos: filter.dll, project.exe. Desea actualizar el código de filtro; usted actualiza filter.dll. ¿Cómo es el escenario dos más barato o más fácil que el escenario uno? En ambos casos, está actualizando un archivo; ¿Por qué importa cuál es el nombre del archivo?

Sin embargo, quizás sea realmente más barato y más fácil para su situación particular. La clave para entender sobre los ensambles es que los ensambles son la unidad más pequeña de , independientemente del código configurable y redistribuible. Si tiene dos cosas y tiene sentido para la versión y enviarlas independientemente una de la otra, entonces deberían estar en ensamblajes diferentes; si no tiene sentido hacer eso, entonces deberían estar en el mismo conjunto.

He leído que las asambleas enlazan a versiones específicas de otros conjuntos, por lo que si puedo actualizar el archivo DLL única, en realidad es considerada la manipulación. ¿Cómo puedo actualizar la DLL sin cambiar el EXE? ¿Para eso sirve una política de editor?

Un conjunto puede recibir un "nombre seguro". Cuando nombra a su conjunto Foo.DLL, y escribe Bar.EXE para decir "Bar.EXE depende de Foo.DLL", entonces el tiempo de ejecución cargará todo lo que pasa por llamarse Foo.DLL; los nombres de los archivos no son fuertes Si un hacker malvado obtiene su propia versión de Foo.DLL en la máquina cliente, el cargador la cargará. Un nombre seguro le permite a Bar.EXE decir "Bar.exe versión 1.2 escrita por Bar Corporation depende de Foo.DLL versión 1.4 escrita por Foo Corporation", y todas las verificaciones se realizan contra las claves criptográficas fuertes asociadas con Foo Corp y Bar Corp.

Así que sí, un ensamblaje puede configurarse para vincularse únicamente con una versión específica de una empresa específica, para evitar manipulaciones. Lo que puede hacer para actualizar un ensamblaje para usar una versión más nueva es crear un pequeño archivo XML que le diga al cargador "¿sabe cómo dije que quería Foo.DLL v1.4? Bueno, en realidad si 1.5 está disponible, está bien usarlo eso también."

¿Qué debo buscar? Veo muchos libros sobre C# y .NET, pero ninguno sobre implementación, construcción o pruebas o cosas que no están relacionadas con el lenguaje en sí.

El despliegue se omite con frecuencia en los libros, estoy de acuerdo.

Comenzaré buscando "ClickOnce" si está interesado en la implementación de aplicaciones administradas de Windows.

1

Los proyectos pueden hacer referencia a conjuntos o proyectos.

Cuando hace referencia a otro ensamblaje/proyecto, puede utilizar todas las clases/enums/structs públicas, etc. en el ensamblaje al que se hace referencia.

No necesita tenerlos todos en una sola solución. Puede tener tres soluciones, una para cada Proceso, y las tres soluciones pueden cargar Motor y Filtro.

Además, podría hacer que el Proceso B y el Proceso C hagan referencia a los ensamblados compilados (los .dll) del Motor y Filtro y que tengan un efecto similar.

Siempre que no establezca la propiedad en la referencia a un ensamblado para requerir una versión específica, puede actualizar libremente las DLL sin mucha preocupación, siempre que los únicos cambios de código se realizaron en la DLL.

Además, la razón principal que separamos el filtro del proceso (sólo un proceso que utiliza) es para que podemos desplegar el filtro de forma independiente del proceso para que el proceso ejecutable no lo hace necesita ser actualizado Independientemente de si esa es la mejor práctica, vamos a rodar con ella. ¿Es esto posible?

En realidad prefiero este método de actualización. Menos sobrecarga para actualizar solo los archivos que cambiaron en vez de todo cada vez.

En cuanto al uso del GAC, no entraré en ningún otro nivel de complejidad.

A prueba de sabotaje sus ensamblajes se pueden hacer firmándolos, lo cual es necesario para utilizar el GAC en primer lugar, pero aún así debe estar bien, siempre que no se requiera una versión específica.

Mi recomendación es leer un libro sobre .NET Framework. Esto realmente te ayudará a entender el CLR y lo que estás haciendo.

Applied Microsoft .NET Framework Programming era un libro que realmente disfruté leyendo.

+0

. La Programación de Microsoft .NET Framework ha sido reemplazada por CLR a través de C# (http://www.amazon.com/CLR-Via-C-Pro-Developer/ dp/0735621632/ref = sr_1_1? ie = UTF8 & s = books & qid = 1264003319 & sr = 1-1) y se publicará una tercera edición (http://www.amazon.com/CLR-via-C-Third-Pro-Developer/dp/0735627045/ref = sr_1_3? Ie = UTF8 & s = books & qid = 1264003319 & sr = 1-3). – jason

+0

Es bueno saberlo, gracias Jason, los verificará. –

1

Menciona que el motor es código compartido, por lo que lo coloca en un proyecto independiente en su solución. No hay nada de malo en hacerlo de esta manera, y no es necesario agregar esta DLL al GAC. Durante su fase de desarrollo, puede agregar una referencia a su proyecto de motor y podrá llamar al código de ese ensamblaje. Cuando desee implementar esta aplicación, puede implementar la DLL del motor con ella, o puede agregar la DLL del motor al GAC (que es otra bola de cera en sí misma). Tiendo a apoyarme en las implementaciones de GAC a menos que sea realmente necesario. Una de las mejores características de .NET es la capacidad de implementar todo lo que necesita para ejecutar su aplicación en una carpeta sin tener que copiar cosas a las carpetas del sistema (es decir, el GAC).

Si desea lograr algo así como cargar dinámicamente los DLL y llamar a los métodos de miembros de su procesador sin preocuparse por la versión específica, puede hacer un par de rutas. La ruta más fácil es simplemente establecer la propiedad Specific Version en False cuando agrega la referencia. Esto le dará la libertad de cambiar la DLL más adelante, y siempre y cuando no se meta con las firmas de métodos, no debería ser un problema. La segunda opción es MEF (que usa Reflection y será parte del framework en .NET 4.0). La idea del MEF es que puede escanear una carpeta de estilo de "complementos" para las DLL que implementan funcionalidades específicas y luego llamarlas dinámicamente. Esto le da cierta flexibilidad adicional ya que puede agregar nuevos conjuntos más adelante sin la necesidad de modificar sus referencias.

Otra cosa a tener en cuenta es que hay plantillas de proyecto de instalación e implementación integradas en Visual Studio que puede usar para generar paquetes MSI para implementar sus proyectos. MSDN tiene una gran cantidad de documentación relacionada con este tema que se puede comprobar a cabo, aquí:

http://msdn.microsoft.com/en-us/library/ybshs20f%28VS.80%29.aspx

1

Do no utilice el GAC en su máquina de compilación, es un detalle de implementación. Visual Studio copia automáticamente la DLL en el directorio de compilación de su aplicación cuando hace referencia a la DLL. Eso asegura que ejecutará y depurará con la versión esperada de la DLL.

Cuando implemente, puede elegir. Puede enviar la DLL junto con la aplicación que la usa, almacenada en la carpeta de instalación de EXE. No se necesita nada especial, el CLR siempre puede encontrar el archivo DLL y no tiene que preocuparse por nombres o versiones fuertes. Se implementa una actualización de corrección de errores simplemente copiando la nueva DLL en la carpeta EXE.

Cuando tiene varias aplicaciones instaladas con una dependencia en la DLL, implementar actualizaciones de corrección de errores puede comenzar a ser incómodo. Ya que tiene que copiar al DLL repetidamente, una vez para cada aplicación. Y puede tener problemas cuando actualiza algunas aplicaciones, pero no otras. Especialmente cuando hay un cambio radical en la interfaz DLL que requiere la recompilación de la aplicación. Eso es DLL Hell knocking, el GAC puede resolver eso.

0

Encontramos some guidance en este número en MSDN. Comenzamos con dos soluciones separadas sin código compartido, y luego resumimos las características comunes a los ensambles compartidos. Tuvimos problemas con las formas de aislar los cambios en el código compartido para afectar solo los proyectos que estaban listos para ello. Fuimos terribles al Open/Close.

Probamos

  • ramas del código compartido para cada proyecto que lo utilizó y su inclusión en la solución
  • copiar el ensamblado compartido de la solución compartida cuando hicimos cambios
  • codificación de pre-construcción eventos para compilar la solución de código compartido y copiar el ensamblaje

Todo fue un verdadero dolor. Terminamos usando una solución grande con todos los proyectos en ella. Realizamos una bifurcación de cada proyecto porque queremos presentar las características más cercanas a la producción. Esto ramifica el código compartido también. Se simplifican mucho las cosas y tenemos una mejor idea de qué pruebas fallan en todos los proyectos, a medida que cambia el código común.

En cuanto a la implementación, nuestros scripts de construcción están configurados para compilar el código y copiar solo los archivos que han cambiado, incluidos los ensamblajes, a nuestros entornos.

0

De forma predeterminada, tiene un número de versión codificada en su proyecto (1.0.0.0). Mientras no lo modifique, puede usar todas las compilaciones de Filtro con el ensamblaje de Proceso (solo sabe que debe usar el 1.0.0.0 versión). Sin embargo, esta no es la mejor solución, porque ¿cómo se puede distinguir entre varias compilaciones?

Otra opción es utilizar diferentes versiones del filtro por el mismo proceso. Debe agregar un archivo app.config al proyecto Process e incluir un elemento bindingRedirect (consulte los documentos). Cada vez que Runtime busca una versión particular del filtro, se "redirecciona" a una versión indicada en la configuración. Desafortunadamente, esto significa que, aunque no tiene que actualizar el ensamblado de Proceso, tendrá que actualizar el archivo de configuración con la nueva versión.

Cada vez que se encuentra con problemas de versiones, puede utilizar Fuslogvw.exe (visor de registro de fusión) para solucionar estos.

divertirse!

ulu

Cuestiones relacionadas