Как мне реализовать мой репозиторий (DDD) в C # для обработки нескольких вызовов для одного и того же совокупного корня - PullRequest
6 голосов
/ 09 февраля 2011

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

Я не использую O / R mapper, поэтому, если есть технология, которая его обрабатывает, мне нужно знать, какон делает это (как и в каком шаблоне он использует), чтобы иметь возможность использовать его

Спасибо!

Ответы [ 3 ]

3 голосов
/ 09 февраля 2011

Полагаю, вы думаете о шаблоне Identity Map , описанном Мартином Фаулером .

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

Я предлагаю получить его превосходную книгу, но выдержка, описывающая этот шаблон, читается в Google Книгах (ищите «карту идентичности Фаулера»).

По сути, карта идентификации - это объект, который хранит, например, в хеш-таблице, объекты сущностей, загруженные из базы данных. Сама карта хранится в контексте текущего сеанса (запроса), предпочтительно в единице работы (для объектов чтения / записи). Для объектов, доступных только для чтения, карта не должна быть привязана к сеансу и может храниться в контексте процесса (глобальное состояние).

1 голос
/ 09 февраля 2011

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

Проще говоря, я не позволяю никакому коду использовать репозиториинапрямую - только Сервисы могут сделать это.Тогда все остальное потребляет соответствующие сервисы в качестве интерфейсов.Это дает вам хорошую оболочку для размещения логики, кэширования и т. Д.

0 голосов
/ 09 февраля 2011

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

Хранилище - это ваша коллекция предметов. Ни один код, потребляющий хранилище, не должен решать, извлекать ли объект из хранилища или откуда-то еще.

Синглтон звучит как неправильная жизнь; скорее всего, это должно быть по запросу. Это легко сделать, если вы используете контейнер IoC / DI.

Похоже, тот факт, что вы даже рассматривали несколько вызовов для одного и того же агрегата, свидетельствует о проблеме архитектуры / дизайна. Мне было бы интересно услышать пример того, какими могут быть эти первый и второй вызовы, и почему они требуют одинакового точного экземпляра вашего AR.

...