Сохраняющаяся зависимость сборки в C# .NET

Мой проект C# - назовем его SuperUI - используется для использования класса из внешней сборки. Сейчас это не так, но компилятор не позволяет мне построить проект без ссылки на сборку. Позвольте мне уточнить.

Этот проект использовался для генерации и перехвата настраиваемого класса исключений - SuperException который был производным от стандартного System.Exception и находился в отдельной предварительно скомпилированной сборке SuperAssembly.DLL, на которую я ссылался.

В конце концов, я решил, что это бессмысленное упражнение, и SuperExceptions в каждом случае заменил все на System.SuitableStandardException. Я удалил ссылку на SuperException.DLL, но теперь при попытке скомпилировать проект сталкиваюсь со следующим:

Тип «SuperException» определен в сборке, на которую нет ссылки. Вы должны добавить ссылку на сборку SuperException, Version = 1.1.0.0 (...)

Исходный файл, на который ссылается ошибка, не кажется актуальным; это пространство имен проекта, которое выделяется в среде IDE.

Вот в чем дело:

  1. Все варианты использования SuperExceptionбыли исключены из кода проекта.
  2. По сравнению с другим проектом, который отлично компилируется без ссылки SuperException.DLL, я ссылаюсь только на еще одну сборку - и не thatссылаюсь ни на что, на что мой проект не ссылается сам. Хотя возможно, что любая из этих зависимостей может вызвать ошибку SuperExceptions, я улавливаю только базовый класс Exception и в любом случае ... другой проект строится нормально!
  3. Я делал «Чистое решение» Visual Studio и много раз очищал все вручную.

Это еще не конец света, чтобы включить эту ссылку, я просто не понимаю, зачем она нужна больше. Нррргг. Любые указатели приветствуются!

Ответов (14)

Решение

Скорее всего, это транзитивная ссылка, где вызов метода какого-либо типа возвращает экземпляр SuperException в коробке («понижающий») как, например, Exception, но при проверке кода в транзитивно включенном коде, то есть кода из вызовов внешнего метода, компилятор знает, что вы в какой-то момент необходимо иметь информацию об этом типе.

Resharper сообщит вам, где вам нужно добавить ссылку, и вы можете использовать Lütz Roeder, также известный как RedGate's Reflector, для сканирования скомпилированного IL для ссылки на этот тип двумя способами: 1) использовать средство поиска, 2) открыть каждый публичный тип, который вы используете, и для того, который требует сборки «призрак», он попросит вас указать его местоположение.

Чаще всего это случается со мной, когда я ссылаюсь на Castle.Windsor, но не на Castle.MicroKernel. :п

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

Звучит довольно странно. Вот что я бы проверил дальше:

  1. Убедитесь, что в вашем файле Properties / AssemblyInfo.cs ничего не осталось.
  2. Убедитесь, что в вашем файле SuperUI.csproj ничего не осталось.
  3. Удалите все ссылки и снова добавьте их.

Спасибо за ваши ответы. Я пробовал все предложения (кроме одного), но безрезультатно.

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

  1. Выйти из Visual Studio
  2. Удалите папки bin и obj в каталоге решения
  3. Перезагрузите и посмотрите, что произойдет

Попробуйте создать новый проект и добавить в него все свои классы.

Поскольку это ошибка компилятора, где-то в проекте должна быть ссылка или использование SuperException.

  1. Выполните поиск / замену всего проекта или решения для этого типа и удалите все ссылки (возможно, вы уже это сделали).
  2. Если вы ссылаетесь на какие-либо типы, унаследованные от SuperException (даже если тип определен в другой сборке), вам потребуется ссылка на сборку, в которой определено SuperException.

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

В настоящее время в проектах VS нет ничего загадочного - это все текстовые файлы и т. Д. ЧТО-ТО должно ссылаться на этот класс / dll, и это что-то должно быть частью вашего проекта.

Вы действительно использовали grep'd или findstr'd для всего дерева решений, каждого отдельного файла для ссылки на это исключение?

Я согласен с другими комментариями здесь .. Где-то есть ссылка простым текстом ! У меня были аналогичные проблемы в прошлом, когда поиск в файлах проекта ничего не возвращал, оказывается, это был какой-то другой файл, который не был автоматически выбран при поиске.

Нет , я не думаю , что создание нового проекта является решением здесь .. Вы должны быть уверены , что НИ ОДИН из ссылок в вашей зависимости использование дерева SuperException .. NONE

Я никогда не сталкивался с этим до такой степени, что мне нужно было буквально стереть проект, я всегда где-то находил ссылку. Убедитесь, что вы ищете каждый файл.

РЕДАКТИРОВАТЬ:

Просто хочу добавить, если местоположение, на которое указывает ошибка, кажется случайным, это часто может означать несоответствие между скомпилированным исходным кодом и файлом исходного кода. Это приложение ASP.NET? У меня было это раньше, когда скомпилированная DLL не была заменена при перестройке в папке temp ASP.NET, что приводило к возникновению ... Интересно при отладке :)

grep -R SuperException * в основе вашего проекта ( grep сначала получить откуда-то) на всякий случай.

Если вы ссылаетесь на какие-либо типы, наследуемые от SuperException (даже если тип определен в другой сборке), вам потребуется ссылка на сборку, в которой определено SuperException.

Прикомандирован к этому.

Возможно, вы не ссылаетесь SuperException, но вы можете ссылаться SpecializedSuperException, что получено из или как-то иначе используется SuperException - ваш grep проекта для SuperException не будет его улавливать.

Попробуйте взломать пробную версию NDepend

Вот где действительно окупаются такие инструменты, как Resharper - простой поиск использования обычно говорит мне о таких «призрачных зависимостях» несколько раз.

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

Я не думаю, что это проблема кода. Что я вижу, так это то, что одна из ваших существующих ссылок, вероятно, полагается на этот тип в своих собственных типах, которые вы, вероятно, создаете в своем приложении.

Если это так, вам нужна эта ссылка, даже если вы явно не используете тип и даже если другая сборка, на которую есть ссылка, имеет свою собственную ссылку. Иногда эта проблема возникает со сторонними компонентами, которым нужны ссылки на типы, на которые вы не ссылались. Компилятор, очевидно, видит что-то в одной из ваших существующих сборок, на которые есть ссылки, и ожидает, что вы укажете зависимую.

У меня была очень похожая проблема со ссылками на сборку, которая возникала, когда моя библиотека C# имела зависимую сборку C++ / CLI. Проблема заключалась в том, что я унаследовал публичный класс от этой сборки C++ / CLI в моей библиотеке сборки C#. Это означало, что цепочка наследования охватывала несколько сборок.

Я надеялся, что любой клиент будет достаточно умен, чтобы косвенно загрузить сборку C++ / CLI в любое время, когда она понадобится библиотеке C#, но это было не так даже во время компиляции.

Я избавился от этой проблемы, нарушив наследование между классами, которые охватывали эти две библиотеки сборки, и вместо этого использовал агрегирование. Мой клиент, наконец, был доволен и ему больше не требовалась сборка C++ / CLI в качестве зависимости.

В вашем слове вам, вероятно, придется убедиться, что SuitableStandardException он не наследуется от SuperException, чтобы исключить SuperException.DLL ссылку в качестве ссылки.

Используйте инкапсуляцию вместо наследования и создайте SuperException член данных в своем новом файле SuitableStandardException .

Если это не решит проблему, у вас может быть больше классов, охватывающих наследование некоторых сборок, в вашем случае SuperAssembly.DLL и superException.dll .

Если вы не можете найти их все, попробуйте следующий трюк:

  1. Сделайте все ваши публичные члены и классы SuperAssembly.DLLвнутренними.

  2. В SuperAssembly.DLL подружитесь с SuperException.DLL:

    [assembly:InternalsVisibleTo("SuperException, PublicKey=0024000004800000....)]
    
  3. Убедитесь, что они создают и удаляют SuperAssembly.DLLссылку из любого клиента, который уже ссылается SuperException.DLL.