En .NET BCL hay referencias circulares entre:
System.dll
ySystem.Xml.dll
System.dll
ySystem.Configuration.dll
System.Xml.dll
ySystem.Configuration.dll
Aquí hay una captura de pantalla de .NET Reflector que muestra lo que quiero decir:
La forma en que Microsoft creó estos ensamblajes es un misterio para mí. ¿Se requiere un proceso de compilación especial para permitir esto? Imagino que aquí está pasando algo interesante.
.net
assemblies
circular-reference
base-class-library
Dibujó Noakes
fuente
fuente
Respuestas:
Solo puedo decir cómo el Proyecto Mono hace esto. El teorema es bastante simple, aunque genera un lío de código.
Primero compilan System.Configuration.dll, sin que la parte necesite la referencia a System.Xml.dll. Después de esto, compilan System.Xml.dll de la forma habitual. Ahora viene la magia. Ellos recompilan System.configuration.dll, con la parte que necesita la referencia a System.Xml.dll. Ahora hay una compilación exitosa con la referencia circular.
En breve:
fuente
RBarryYoung y Dykam están en algo. Microsoft usa una herramienta interna que usa ILDASM para desensamblar ensamblajes, quitar todo el material interno / privado y cuerpos de métodos y recompilar IL nuevamente (usando ILASM) en lo que se llama 'ensamblaje deshidratado' o ensamblaje de metadatos. Esto se hace cada vez que se cambia la interfaz pública de ensamblado.
Durante la compilación, se utilizan ensamblados de metadatos en lugar de los reales. De esa manera se rompe el ciclo.
fuente
Se puede hacer de la forma descrita por Dykam, pero Visual Studio le impide hacerlo.
Tendrá que usar el compilador de línea de comandos csc.exe directamente.
csc / target: biblioteca ClassA.cs
csc / target: biblioteca ClassB.cs /reference:ClassA.dll
csc / target: biblioteca ClassA.cs ClassC.cs /reference:ClassB.dll
fuente
Es bastante fácil de hacer en Visual Studio siempre que no use referencias de proyecto ... Pruebe esto:
Así que así es como lo haces. Pero en serio ... ¡No lo hagas NUNCA en un proyecto real! Si lo hace, Santa no le traerá ningún regalo este año.
fuente
Supongo que podría hacerse comenzando con un conjunto acíclico de ensamblajes y usando ILMerge para luego fusionar los ensamblajes más pequeños en grupos relacionados lógicamente.
fuente
Bueno, nunca lo he hecho en Windows, pero lo he hecho en muchos de los entornos compile-link-rtl que sirvieron como progenitores prácticos para ello. Lo que debe hacer primero es crear "destinos" de código auxiliar sin las referencias cruzadas, luego vincular, luego agregar las referencias circulares y luego volver a vincular. A los enlazadores generalmente no les importan las referencias circulares o las siguientes cadenas de referencias, solo les importa poder resolver cada referencia por sí misma.
Entonces, si tiene dos bibliotecas, A y B que necesitan hacer referencia entre sí, intente algo como esto:
Dykam tiene un buen punto, se compila, no se vincula en .Net, pero el principio sigue siendo el mismo: haga sus fuentes con referencias cruzadas, con sus puntos de entrada exportados, pero con todas menos una que tengan sus propias referencias a las demás. fuera. Constrúyalos así. Luego, elimine las referencias externas y vuelva a generarlas. Esto debería funcionar incluso sin herramientas especiales, de hecho, este enfoque ha funcionado en todos los sistemas operativos en los que lo he probado (alrededor de 6 de ellos). Aunque obviamente algo que lo automatice sería de gran ayuda.
fuente
Un enfoque posible es usar la compilación condicional (#if) para compilar primero un System.dll que no dependa de esos otros ensamblados, luego compilar los otros ensamblajes y, por último, volver a compilar System.dll para incluir las partes que dependen de Xml y Configuración.
fuente
Técnicamente, es posible que estos no se hayan compilado y ensamblado a mano. Estas son bibliotecas de bajo nivel, después de todo.
fuente