Мне кажется, у тебя две проблемы.
Сначала вам нужно разбить ориентированную на бизнес функциональность системы на сплоченные части; с точки зрения объектно-ориентированного дизайна, есть несколько принципов, которые вы должны использовать, чтобы направить свое мышление:
Идея заключается в том, что вещи, которые тесно связаны, в той степени, что «если нужно что-то изменить, все они, вероятно, должны быть изменены».
Не пытайтесь заставить компонент делать слишком много.
Я думаю, вам также нужно более внимательно взглянуть на свою структуру зависимостей - как только вы начнете получать циклические ссылки, это, вероятно, признак того, что вы неправильно разбили различные «вещи». Может быть, вам нужно больше понять проблемную область? Это общая проблема - ну, не столько проблема, сколько просто часть проектирования сложных систем.
Как только вы разберетесь с этим, это облегчит вторую часть: архитектуру и дизайн системы.
К счастью, в плагинах уже много материала, попробуйте поискать по тегу, например:
Edit:
Активы определены в другом модуле, чем сотрудники. Но класс Assets определяет свойство AssignedTo, которое имеет тип «Сотрудник». Я ломал голову, как отключить эти два
Здесь есть две части, и вы можете захотеть взглянуть на обе:
- Использование общего уровня, содержащего простые структуры данных, которые могут совместно использоваться всеми частями системы.
- Использование интерфейсов.
Общий слой / POCO's
POCO означает «Простые старые объекты CLR», идея в том, что POCO - это простые структуры данных, которые вы можете использовать для обмена информацией между слоями или, в вашем случае, между модулями, которые должны оставаться свободно связанными. POCO не содержат никакой бизнес-логики. Относитесь к ним так же, как к типам String или DateTime.
Таким образом, вместо того, чтобы ссылаться друг на друга, классы Asset и Employee ссылаются на POCO.
Идея состоит в том, чтобы определить их в общей сборке, на которую могут ссылаться остальные ваши приложения / модули. Сборка, которая определяет их, должна быть лишена нежелательных зависимостей, что должно быть достаточно простым.
Интерфейсы
Это почти то же самое, но вместо ссылки на конкретный объект (например, POCO) вы обращаетесь к интерфейсу. Эти интерфейсы будут определены аналогично описанному выше POCO (общая сборка, без зависимостей).
Затем вы использовали бы Factory и загружали конкретный объект во время выполнения. Это в основном инверсия зависимости.
Таким образом, вместо ссылок друг на друга, классы Asset и Employee ссылаются на интерфейсы, а конкретные реализации создаются во время выполнения.
Эта статья может быть полезна для обоих вариантов выше: Введение в инверсию зависимостей
Edit:
У меня есть следующий метод GetAsset (int assetID); В этом методе заполняется свойство asset.AssignedTo (тип IAssignable). Как это правильно назначить?
Это зависит от того, где находится логика и как вы хотите создавать вещи.
Если у вас есть уровень бизнес-логики (BL), который в основном представляет собой комплексную модель предметной области (DM) (членами которой были и актив, и сотрудник), то, скорее всего, активы и участники будут знать друг о друге, а когда выполнив вызов для заполнения Актива, вы, вероятно, также получите соответствующие данные Сотрудника. В этом случае BL / DM запрашивает данные - не изолированные классы активов и членов.
В этом случае вашими "модулями" будет другой слой, который был построен поверх BL / DM, описанного выше.
Разница в том, что внутри GetAsset () вы получаете только данные об активах, и после этого вы получаете данные о сотрудниках отдельно. Независимо от того, насколько свободно вы соединяете вещи, должна быть какая-то точка , в которой вы определяете связь между активом и сотрудником, даже если это просто данные.
Это предполагает какой-то шаблон регистра, место, где определены «соединения», и каждый раз, когда вы имеете дело с типом «IAssignable», вы знаете, что нужно проверять регистр на наличие возможных назначений.