Можно ли включить циклические зависимости в Visual Studio на уровне сборки?Будут ли возможны взаимозависимые сборки? - PullRequest
15 голосов
/ 03 июля 2010

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

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

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

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

Для меня имело бы смысл, если бы вы сказали: «две сборки не могут зависеть друг от друга, потому что компилятор не может скомпилировать одну перед другой»; за исключением того, что кажется, что вы можете сделать один и тот же аргумент для двух классов в одной сборке, и ясно, что компилятор может справиться с этим сценарием просто отлично.

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

Итак, мой вопрос (три раза):

  1. Возможно ли включить это поведение (в данном случае в Visual Studio или в другом месте)?
  2. Если это невозможно в какой-либо IDE, теоретически это возможно по крайней мере или могут существовать взаимозависимые сборки?
  3. Если это даже теоретически невозможно, то почему бы и нет? Другими словами, чем взаимно зависимые сборки отличаются от взаимно зависимого кода в одной сборке?

Ответы [ 5 ]

12 голосов
/ 03 июля 2010

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

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

  1. Сборка A
  2. Сборка B
  3. Заглушка в сборе B

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

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

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

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

Примечание:

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

ДАЛЕЕ:

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

6 голосов
/ 29 августа 2010

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

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

alt text

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

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

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

2 голосов
/ 03 июля 2010

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

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

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

1 голос
/ 19 октября 2010

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

Однако я не ожидаю, что Visiual Studio когда-либо превзойдет это.


Есть также трюк, который заставит компоновщик перенаправитьзапрос типа из одной сборки в другую.Microsoft использует их, а затем перемещает типы в рамках .net.Это имеет значение только в том случае, если вы не можете получить все ваши вызывающие абоненты для перекомпиляции там кода.

0 голосов
/ 04 декабря 2015

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

...