Сколько UnitsOfWork и репозиториев мне нужно и как связать их с базовым хранилищем?
Давайте рассмотрим следующую ситуацию. Я хочу создать службу WCF, которая предоставляет некоторые методы для конкретных бизнес-операций.
Я пока не знаю, что и сколько базовых механизмов хранения будет использоваться системой. Сегодня это база данных через NHibernate. Завтра нам может понадобиться подключиться к какой-либо устаревшей службе XML или, возможно, даже к файловой системе или FTP. Мне просто нужно спроектировать свои UoW (единицу работы) и репозитории (скорее всего, общие), чтобы бизнес-уровень не заботился о том, какое базовое хранилище используется.
Мой бизнес-уровень перенесен в совершенно отдельные классы, которые обращаются к репозиториям через некоторый интерфейс IRepository, чтобы избежать связывания бизнес-логики с базовым типом репозитория.
У меня есть некоторая конфигурация, которая позволяет мне определить, какое базовое хранилище следует использовать для каждого запрашиваемого типа бизнес-объекта.
Я знаю, что NHibernate ISession, по сути, выполняет работу единицы работы. Означает ли это, что я должен подключить свой UoW к базовому движку? Это означает, что мне понадобится UnitOfWOrkFactory, который создает необходимый HibernateUnitOfWork или RemoteFtpUnitOfWork, а затем мой общий репозиторий получит конкретную единицу работы, получит базовый ISession (или некоторый другой пользовательский базовый поставщик хранилища) и будет работать на Это. Это как это должно работать?
Я знаю, что UoW должен иметь возможность работать с несколькими хранилищами. Но нормально ли для UoW работать с несколькими различными типами репозиториев (например, чтение файла из репозитория FTP, передача данных через некоторые невосприимчивые бизнес-методы и затем сохранение данных в репозитории базы данных)? Или, может быть, единица работы всегда относится только к одному конкретному виду хранения? Я предполагаю, что мы почти попадаем в зону распределенных транзакций, так что это становится все сложнее, но я хочу сделать это правильно с самого начала.
Или это другой путь - у меня должно быть несколько определенных репозиториев, таких как HibernateRepository, FtpRepository, но единице работы все равно, какой репозиторий (и основное хранилище) он использует?
Или, может быть, я должен сделать их обоих специфичными для основного хранилища?
РЕДАКТИРОВАТЬ:
Хм, я только что нашел это: Практическое использование шаблонов Unit of Work & Repository
Поэтому я думаю, что это может работать так: и UoW, и Repository являются специфическими для основного хранилища, но Repository используется только для извлечения данных, а UoW используется для маркировки изменений и их фиксации.
Есть только одна проблема с таким подходом - я не могу себе представить, как я могу охватить одно UoW по разным типам репозиториев, если само UoW связано только с одним конкретным типом базового хранилища.
Еще одно решение, которое приходит мне в голову: я могу создать несколько сложных UoW, способных одновременно управлять несколькими базовыми хранилищами. Но теперь возникает вопрос - что делать с репозиториями? Создать ли тип репозитория для хранилища или снова какой-нибудь универсальный репозиторий, который не знает о базовом хранилище, но получает доступ к хранилищу через некоторый интерфейс IStorageProvider.
Для согласованности использования я мог бы создать структуру следующим образом:
- UoW с методами Delete/Insert/Commit, а также с методами Get - поэтому базовая бизнес-логика не должна иметь дело как с UoW, так и с репозиториями, а вызывает только методы UoW
- Сам UoW имеет дело с различными типами репозиториев и перенаправляет вызовы Get/Query (или Save, если необходимо) в соответствующие репозитории. Я думаю, я попробую это и посмотрю, как это получится.