C # - Циркуляр Ссылка и не может видеть пространство имен - PullRequest
1 голос
/ 02 июня 2009

У меня есть решение с 2 проектами.

One, Raven, это простая база, которая предоставляет данные для второго проекта, PPather, с которым можно что-то делать. Второй проект зависит от первого, чтобы скомпилировать, поэтому для его сборки я добавлю ссылку на Raven. Пока все работает хорошо.

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

Кто-нибудь знает, как я могу заставить Равена увидеть пространство имен проекта PPather, которое от него зависит?

Ответы [ 5 ]

13 голосов
/ 02 июня 2009

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

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

2 голосов
/ 02 июня 2009

Как говорит Эндрю, вы не можете, и в этом нет особого смысла.

В основном, выполните одно из следующих действий:

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

  • Перепроектируйте сборки так, чтобы они не зависели друг от друга напрямую в обоих направлениях; например, сборка A зависит от интерфейса, определенного в сборке C, и сборка B должна реализовывать этот интерфейс (оба зависят от C).

0 голосов
/ 02 июня 2009

Разветвите calsses в вороне, которые Пантера должна использовать из ворона, в другое собрание, и пусть пантера и ворон ссылаются на них.

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

0 голосов
/ 02 июня 2009

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

Вы хотите, чтобы Raven запустил PPather? Является ли PPather консольным / оконным приложением? Для этого используйте Process.Start (и где-нибудь сохраните местоположение PPather в реестре).

В качестве альтернативы создайте интерфейсы для классов, которые вам нужны, из PPather - и заставьте классы в PPather реализовать эти интерфейсы.

interface IPPatherInterface // Inside of Raven.
{
    void Foo();
}

class PPatherClass : IPPatherInterface // Inside of PPather
{
    // ...
}

class SomeRavenClass // Static maybe? Inside of Raven
{
    void SupplyPPatherClass(IPPatherInterface item) { ... }
}

Теперь у вас есть возможность для PPather предоставить реализацию этого интерфейса в Raven.

0 голосов
/ 02 июня 2009

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

Кажется, что Raven является отправной точкой, поэтому одним из возможных решений является создание базового класса или интерфейса в компоненте PPather, который отражает набор функций, которые PPather ищет в Raven. Затем Raven может реализовать этот базовый класс и затем включить указатель this при создании / вызове PPather. PPather будет ожидать указатель на базовый класс (или интерфейс) в своей собственной сборке, и поэтому никогда не будет «знать» о Raven, кроме как через собственную абстракцию. Следовательно, циклическая зависимость будет нарушена (посредством внедрения зависимости).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...