В .NET BCL существуют циклические ссылки между:
System.dll
иSystem.Xml.dll
System.dll
иSystem.Configuration.dll
System.Xml.dll
иSystem.Configuration.dll
Вот скриншот из .NET Reflector, который показывает, что я имею в виду:
Как Microsoft создавала эти сборки, для меня загадка. Требуется ли для этого специальный процесс компиляции? Я предполагаю, что здесь происходит что-то интересное.
Ответы:
Я могу только сказать, как это делает Mono Project. Теорема довольно проста, хотя и вносит путаницу в код.
Сначала они компилируют System.Configuration.dll без той части, которая требует ссылки на System.Xml.dll. После этого они компилируют System.Xml.dll обычным способом. Теперь пришло волшебство. Они перекомпилируют System.configuration.dll, при этом часть требует ссылки на System.Xml.dll. Теперь есть успешная компиляция с круговой ссылкой.
Коротко:
источник
RBarryYoung и Dykam кое-что понимают. Microsoft использует внутренний инструмент, который использует ILDASM для дизассемблирования сборок, удаления всех внутренних / личных вещей и тел методов и повторной компиляции IL (с использованием ILASM) в так называемую «обезвоженную сборку» или сборку метаданных. Это происходит каждый раз при изменении публичного интерфейса сборки.
Во время сборки используются сборки метаданных вместо реальных. Таким образом, цикл нарушен.
источник
Это можно сделать так, как описано в Dykam, но Visual Studio не дает вам этого сделать.
Вам придется напрямую использовать компилятор командной строки csc.exe.
csc / target: библиотека ClassA.cs
csc / target: библиотека ClassB.cs /reference:ClassA.dll
csc / target: библиотека ClassA.cs ClassC.cs /reference:ClassB.dll
источник
Это довольно просто сделать в Visual Studio, если вы не используете ссылки на проекты ... Попробуйте следующее:
Вот как вы это делаете. А если серьезно ... НИКОГДА не делайте этого в реальном проекте! Если вы это сделаете, Санта в этом году не принесет вам подарков.
источник
Я предполагаю, что это можно было бы сделать, начав с ациклического набора сборок и используя ILMerge, чтобы затем объединить более мелкие сборки в логически связанные группы.
источник
Что ж, я никогда не делал этого в Windows, но я делал это во многих средах compile-link-rtl, которые послужили его практическими прародителями. Что вы делаете, так это сначала создаете «цели» заглушки без перекрестных ссылок, затем связываете, затем добавляете циклические ссылки, а затем повторно связываете. Компоновщики обычно не заботятся о циклических ссылках или следовании цепочкам ссылок, они заботятся только о том, чтобы иметь возможность разрешить каждую ссылку самостоятельно.
Итак, если у вас есть две библиотеки, A и B, которые должны ссылаться друг на друга, попробуйте что-то вроде этого:
Dykam делает хорошее замечание: он компилируется, а не ссылается на .Net, но принцип остается тем же: сделайте ваши источники перекрестными ссылками с их экспортированными точками входа, но со всеми, кроме одного, со своими собственными ссылками на другие заглушки вне. Постройте их вот так. Затем отключите внешние ссылки и перестройте их. Это должно работать даже без каких-либо специальных инструментов. Фактически, этот подход работал во всех операционных системах, в которых я когда-либо пробовал (около 6 из них). Хотя, очевидно, что-то, что автоматизирует, было бы большим подспорьем.
источник
Один из возможных подходов - использовать условную компиляцию (#if), чтобы сначала скомпилировать System.dll, которая не зависит от этих других сборок, затем скомпилировать другие сборки и, наконец, перекомпилировать System.dll, чтобы включить части, зависящие от Xml и Конфигурация.
источник
Технически возможно, что они вообще не были скомпилированы, а собраны вручную. В конце концов, это библиотеки низкого уровня.
источник