No .NET BCL, existem referências circulares entre:
System.dll
eSystem.Xml.dll
System.dll
eSystem.Configuration.dll
System.Xml.dll
eSystem.Configuration.dll
Aqui está uma captura de tela do .NET Reflector que mostra o que quero dizer:
Como a Microsoft criou esses assemblies é um mistério para mim. É necessário um processo de compilação especial para permitir isso? Eu imagino que algo interessante está acontecendo aqui.
.net
assemblies
circular-reference
base-class-library
Drew Noakes
fonte
fonte
Respostas:
Só posso dizer como o Projeto Mono faz isso. O teorema é bastante simples, embora confunda o código.
Eles primeiro compilam System.Configuration.dll, sem que a parte precise da referência a System.Xml.dll. Depois disso, eles compilam System.Xml.dll da maneira normal. Agora vem a magia. Eles recompilaram System.configuration.dll, com a parte precisando da referência a System.Xml.dll. Agora há uma compilação bem-sucedida com a referência circular.
Em resumo:
fonte
RBarryYoung e Dykam estão no caminho certo. A Microsoft usa uma ferramenta interna que usa ILDASM para desmontar assemblies, remover todas as coisas internas / privadas e corpos de método e recompilar IL novamente (usando ILASM) no que é chamado de 'montagem desidratada' ou montagem de metadados. Isso é feito toda vez que a interface pública da montagem é alterada.
Durante a construção, assemblies de metadados são usados em vez de reais. Dessa forma, o ciclo é quebrado.
fonte
Isso pode ser feito da maneira que Dykam descreveu, mas o Visual Studio impede você de fazê-lo.
Você terá que usar o compilador de linha de comando csc.exe diretamente.
csc / target: biblioteca ClassA.cs
csc / target: biblioteca ClassB.cs /reference:ClassA.dll
csc / target: biblioteca ClassA.cs ClassC.cs /reference:ClassB.dll
fonte
É muito fácil de fazer no Visual Studio, desde que você não use referências de projeto ... Experimente isto:
Então é assim que você faz. Mas falando sério ... Nunca faça isso em um projeto real! Se você fizer isso, o Papai Noel não vai lhe trazer nenhum presente este ano.
fonte
Acho que isso poderia ser feito começando com um conjunto acíclico de assemblies e usando ILMerge para unir os assemblies menores em grupos logicamente relacionados.
fonte
Bem, eu nunca fiz isso no Windows, mas fiz em muitos dos ambientes compile-link-rtl que serviram como progenitores práticos para ele. O que você faz é primeiro fazer stub "alvos" sem as referências cruzadas, em seguida, vincular, adicionar as referências circulares e, em seguida, vincular novamente. Os linkers geralmente não se preocupam com refs circulares ou cadeias de refs seguintes, eles só se preocupam em resolver cada referência por conta própria.
Portanto, se você tiver duas bibliotecas, A e B, que precisam fazer referência uma à outra, tente algo assim:
Dykam faz um bom ponto, é compilar, não vincular em .Net, mas o princípio permanece o mesmo: Faça suas fontes com referência cruzada, com seus pontos de entrada exportados, mas com todos, exceto um, tendo suas próprias referências aos outros esboçados Fora. Construa-os assim. Em seguida, remova as referências externas e reconstrua-as. Isso deve funcionar mesmo sem nenhuma ferramenta especial; na verdade, essa abordagem funcionou em todos os sistemas operacionais em que já experimentei (cerca de 6 deles). Embora obviamente algo que o automatize seria uma grande ajuda.
fonte
Uma abordagem possível é usar a compilação condicional (#if) para primeiro compilar um System.dll que não depende desses outros assemblies, em seguida, compilar os outros assemblies e, por último, recompilar System.dll para incluir as partes que dependem de Xml e Configuração.
fonte
Tecnicamente, é possível que eles não tenham sido compilados e montados manualmente. Afinal, são bibliotecas de baixo nível.
fonte