una saber referencias referencia quito permitir hay eliminar donde detectar datos cómo como circulares buscar .net assemblies circular-reference bcl

.net - saber - referencia circular base de datos



¿Cómo creó Microsoft ensamblajes que tienen referencias circulares? (8)

Bueno, nunca lo hice en Windows, pero lo he hecho en muchos de los entornos compile-link-rtl que servían como los progenitores prácticos para ello. Lo que debe hacer primero es crear "objetivos" sin las referencias cruzadas, luego vincular, luego agregar las referencias circulares, luego volver a vincular. En general, los vinculadores no se preocupan por los ref circulares ni por las cadenas de ref, solo se preocupan por poder resolver cada referencia por sí mismos.

Entonces, si tiene dos bibliotecas, A y B que necesitan referenciarse, intente algo como esto:

  1. Enlace A sin referencias a B.
  2. Enlace B con referencias a A.
  3. Enlace A, agregando los refs a B.

Dykam hace un buen punto, es compilar, no enlazar en .Net, pero el principio sigue siendo el mismo: hacer sus referencias cruzadas, con sus puntos de entrada exportados, pero con todos menos uno de ellos teniendo sus propias referencias a los otros apalabrados fuera. Constrúyalos así. Luego, quita las referencias externas y reconstruyelas. Esto debería funcionar incluso sin herramientas especiales, de hecho, este enfoque ha funcionado en todos los sistemas operativos en los que lo haya probado alguna vez (alrededor de 6 de ellos). Aunque obviamente algo que lo automatiza sería una gran ayuda.

En .NET BCL hay referencias circulares entre:

  • System.dll y System.Xml.dll
  • System.dll y System.Configuration.dll
  • System.Xml.dll y System.Configuration.dll

Aquí hay una captura de pantalla de .NET Reflector que muestra lo que quiero decir:

Cómo creó Microsoft estos conjuntos es un misterio para mí. ¿Se requiere un proceso de compilación especial para permitir esto? Imagino que algo interesante está sucediendo aquí.


Es bastante fácil de hacer en Visual Studio siempre que no uses referencias de proyectos ... Prueba esto:

  1. Abrir estudio visual
  2. Cree 2 proyectos de Class Library "ClassLibrary1" y "ClassLibrary2".
  3. Construir
  4. Desde ClassLibrary1 agregue una referencia a ClassLibrary2 navegando al dll creado en el paso 3.
  5. Desde ClassLibrary2 agregue una referencia a ClassLibrary1 navegando al dll creado en el paso 3.
  6. Compila de nuevo (Nota: si realizas cambios en ambos proyectos necesitarías compilar dos veces para que ambas referencias sean "nuevas")

Así que así es como lo haces. Pero en serio ... ¡Nunca lo hagas en un proyecto real! Si lo haces, Santa no te traerá ningún regalo este año.


RBarryYoung y Dykam están en algo. Microsoft usa una herramienta interna que usa ILDASM para desmontar ensamblajes, eliminar todos los elementos internos y privados y los cuerpos de métodos, y recompilar IL nuevamente (usando ILASM) en lo que se denomina ''ensamblaje deshidratado'' o ensamblaje de metadatos. Esto se hace cada vez que se cambia la interfaz pública de ensamblaje.

Durante la compilación, se utilizan conjuntos de metadatos en lugar de los reales. De esa manera el ciclo se rompe.


Se puede hacer como Dykam lo describió, pero Visual Studio te impide hacerlo.

Tendrá que usar directamente el compilador de línea de comandos csc.exe.

  1. csc / target: biblioteca ClassA.cs

  2. csc / target: library ClassB.cs /reference:ClassA.dll

  3. csc / destino: biblioteca ClassA.cs ClassC.cs /reference:ClassB.dll

//ClassA.cs namespace CircularA { public class ClassA { } } //ClassB.cs using CircularA; namespace CircularB { public class ClassB : ClassA { } } //ClassC.cs namespace CircularA { class ClassC : ClassB { } }


Solo puedo decir cómo el Proyecto Mono hace esto. El teorema es bastante simple, aunque da un desorden 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 manera normal. Ahora viene la magia. 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:

  • A se compila sin el código que necesita B y la referencia a B.
  • B está compilado.
  • A se recompila.

Supongo que se podría hacer comenzando con un conjunto acíclico de ensamblajes y utilizando ILMerge para luego fusionar los ensamblajes más pequeños en grupos lógicamente relacionados.


Técnicamente, es posible que estos no se hayan compilado en absoluto y se hayan ensamblado a mano. Estas son bibliotecas de bajo nivel, después de todo.


Un posible enfoque es utilizar la compilación condicional (#if) para compilar primero un System.dll que no dependa de esos otros ensamblajes, luego compilar los otros ensamblajes y finalmente recompilar System.dll para incluir las partes que dependen de Xml y Configuración.