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

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

Идея Orchard кажется в ограничении модели данных только одним модулем без намерения иметь какое-либо отношение к модели данных других модулей.

Слово «ограничить», возможно, несколько резкое или неточное — возможно, «ограничить» здесь будет лучшим выбором формулировки. Имея два модуля, A и B, и работая над модулем A, мы можем добавить ссылку на модуль B и использовать репозитории для сущностей из него. Но при работе над модулем B и необходимости доступа к данным из модуля A мы не можем — по крайней мере, не изящно в рамках фреймворка. Здесь существует проблема круговой ссылки.

В этом случае я склоняюсь к нескольким подходам:

  1. объединить два модуля в один (и иметь дело с потенциально обременительной и рискованной миграцией данных)
  2. прибегать к доступу к данным напрямую, без использования фреймворка или репозитория
  3. поместите все модели данных в один модуль, на который ссылаются все другие пользовательские модули (опять же, больше риска переноса данных)
  4. поднимите руку сюда...

Является ли что-то из этого правильной интерпретацией намерений разработчиков программного обеспечения Orchard в отношении модулей и отношений данных?


person JonH    schedule 23.09.2015    source источник
comment
Если 2 модуля зависят друг от друга, они должны быть одним. Или вы должны поместить все общие данные в отдельный модуль, что и другие ссылки. В любом другом случае ваша модель данных может быть неверной, если вам нужна циклическая ссылка.   -  person devqon    schedule 24.09.2015


Ответы (1)


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

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

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

person Marek Dzikiewicz    schedule 24.09.2015
comment
Это похоже на то, что я имел в виду для пунктов 1 и 3 выше. В общем, это предпочтительный способ сделать вещи слабо связанными — кодирование для интерфейсов вместо конкретных реализаций. Это хороший бонус к вашему ответу, чтобы иметь здесь пример для подражания с ядром Orchard. - person JonH; 28.09.2015