Как бороться с циркулярными ссылками? - PullRequest
27 голосов
/ 15 сентября 2010

Если у меня есть эти два проекта:

MyCompany.ERP.Billing
MyCompany.ERP.Financial

Биллинг запрашивает / отправляет информацию на Финансовый и наоборот. Оба слишком велики, поэтому я не хочу помещать их в один проект. Visual Studio не допускает циклические ссылки. Как бы вы справились с этим?

Ответы [ 4 ]

24 голосов
/ 15 сентября 2010

Извлекает интерфейсы из ваших классов и помещает их в основной проект, на который ссылаются как проекты Billing, так и Financial.Затем вы можете использовать эти интерфейсы для обмена данными между сборками.

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

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

5 голосов
/ 15 сентября 2010

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

3 голосов
/ 15 сентября 2010

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

Что-то вроде этого должно работать:

Finance: References Billing, Interfaces, Factory
Billing: References Finance, Interfaces, Factory
Factory: References Interfaces

Фабрика будет иметь BillingFactory.CreateInstance() As Interfaces.IBilling, а также рефератКласс биллинга, который реализует Interfaces.IBilling.

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

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

Это решение может оказаться обходным путем для циклической эталонной задачи. В основном вы используете логику #if вокруг кода, который не компилируется, если ссылка не существует, и вы используете условную компиляцию в файле проекта для определения переменной, только если существует необходимая сборка. В результате при первой загрузке из исходного кода или после очистки решения необходимо выполнить компиляцию дважды. Последующие сборки / перестройки требуют только 1 сборки как обычно. Приятно то, что вам никогда не придется вручную комментировать / раскомментировать #define заявления.

...