Действительно ли возможно включить круговые зависимости в Visual Studio на уровне ассемблера? Взаимно зависимые сборки даже были бы возможны?

Это, вероятно, походит на глупый вопрос, но я собираюсь дать ему выстрел так или иначе.

Таким образом в Visual Studio, у Вас не может быть двух проектов X и Y, таким образом что ссылки Перекрестных ссылок Y и Y X.

В целом я могу полностью понять, как наличие круговой зависимости может быть проблематичным по ряду причин.

Но разве действительно не возможно скомпилировать два проекта, которые являются взаимозависимыми таким образом? Мне кажется, что это должно быть возможно, с тех пор (в моем уме - возможно, я являюсь абсолютно неосновным об этом) наличие двух взаимно зависимых сборок действительно не так отличается от наличия двух взаимно зависимых классов - дело, которое является судебным и может быть скомпилировано.

Это имело бы смысл мне, если бы Вы сказали, "два блока не могут зависеть друг от друга, потому что компилятор не мог скомпилировать тот перед другой"; за исключением того, что кажется, что Вы могли привести тот же аргумент в пользу двух классов в рамках того же блока, и ясно компилятор может иметь дело с этим сценарием очень хорошо.

В основном причина, которую я спрашиваю, не состоит в том, что у меня есть некоторое отчаянное требование сделать эту вещь, которую я знаю, обычно опрометчиво так или иначе. Конкретно я задаюсь вопросом, потому что было бы хорошо, если у меня могло бы быть два проекта - говорят, MyProjectCS и MyProjectVB - который существовал в основном как две взаимно зависимых части единого блока и был только отдельным, потому что определенные части были записаны в C#, и другие части были записаны в VB.NET.

Так, мой вопрос (yikes, втрое):

  1. Действительно ли возможно включить это поведение (в Visual Studio, или в другом месте, в этом отношении)?
  2. Если это не возможно ни в каком IDE, это по крайней мере теоретически возможно, или взаимно зависимые сборки не могли возможно существовать?
  3. Если это даже не теоретически возможно, почему нет? Другими словами, как взаимно зависимые сборки отличаются от взаимно зависимого кода в рамках единственного блока?
15
задан Dan Tao 22 August 2012 в 16:32
поделиться

3 ответа

Я не знаю, как это сделать в IDE; однако это возможно построить через компилируемый процесс сборки.

Вам понадобится:

  1. Assembly A
  2. Assembly B
  3. Stub Assembly B

где Stub Assembly B содержит публичные классы и публичные методы Assembly B и тот же AssemblyInfo.* и ссылается на тот же публичный ключ.

Порядок сборки:

  1. Скомпилировать Stub Assembly B
  2. Скопировать Stub Assembly B в выходной каталог Assembly B
  3. Собрать сборку A
  4. Собрать сборку B

Обратите внимание, что вы не можете иметь прямые ссылки на циклы типов в сигнатурах методов; однако вы можете иметь эффективные циклы путем приведения через объект.

ПРИМЕЧАНИЕ:

ilasm может компилировать истинные взаимно рекурсивные сборки, поскольку каким-то образом он может разрешать типы, которые не существуют во время компиляции.

ДАЛЕЕ:

aspnet_compiler, похоже, может смешивать разные языки в одном проекте (кто знает, как).

12
ответ дан 1 December 2019 в 03:34
поделиться

Я не знаю, как это будет работать в VB, но теоретически должно быть возможно использовать некий заполнитель, указывающий на другой (генерирующий нелегальный код) для компиляции одного из них, а затем использовать его для компиляции другого, а затем перекомпилировать первый.

Именно так, например, работает разрешение круговой зависимости при компиляции программ, которые требуют друг друга.

- Хотя обычно это делается путем отключения функций, которые еще не существуют

2
ответ дан 1 December 2019 в 03:34
поделиться

Несмотря на то, что сборки mscorlib.dll и System.dll взаимозависимы, я бы посоветовал никогда не иметь двух взаимозависимых сборок.

Что касается циклов зависимости между зависаниями, такими как пространства имен, я бы посоветовал использовать NDepend для обнаружения и предотвращения циклов зависимости.

alt text

Выдержка из статьи (я написал): Управляйте зависимостями компонентов, чтобы получить чистую архитектуру.

Циклы зависимостей между компонентами приводят к тому, что обычно называют спагетти-кодом или запутанным кодом. Если компонент A зависит от B, который зависит от C, который зависит от A, компонент A не может быть разработан и протестирован независимо от B и C. A, B и C образуют неделимое целое, своего рода суперкомпонент. Этот суперкомпонент имеет более высокую стоимость, чем сумма затрат на A, B и C, из-за неэкономичности эффекта масштаба (хорошо задокументировано в «Оценка программного обеспечения: демистификация черного искусства» Стива МакКоннелла). По сути, это означает, что стоимость разработки неделимого фрагмента кода возрастает экспоненциально.

Это говорит о том, что разработка и поддержка 1000 LOC (строк кода), вероятно, будет стоить в три или четыре раза дороже, чем разработка и поддержка 500 LOC, если только их нельзя разделить на две независимые части по 500 LOC в каждой. Отсюда и сравнение со спагетти, описывающее запутанный код, который невозможно поддерживать. Чтобы рационализировать архитектуру, необходимо убедиться, что между компонентами нет циклов зависимости, а также убедиться, что размер каждого компонента является приемлемым (от 500 до 1000 LOC).

6
ответ дан 1 December 2019 в 03:34
поделиться