Как класс единицы работы узнает, какой репозиторий вызывать при коммите? - PullRequest
1 голос
/ 25 сентября 2011

* Предисловие: Я довольно плохо знаком с моделью работы *

Моя цель - реализовать единицу рабочего класса, которая сможет отслеживать все объекты, которые были изменены в ходе данной транзакции. Все, что я читал о шаблоне единицы работы, тесно связано с шаблоном хранилища. Так что это подход, который я хотел бы использовать.

Скажем, например, я создаю нового пользователя. На моем объекте единицы работы у меня есть список вновь созданных объектов, поэтому я добавляю нового пользователя в этот список. В моем хранилище пользователей есть метод под названием Create, который принимает пользователя и вызывает хранимую процедуру для добавления данных в базу данных. Когда я вызываю commit для моей единицы работы, как он узнает, какой репозиторий и метод вызывать, основываясь на списке новых объектов? Скажем, он содержит объект User и объект Comment. Оба они созданы и должны быть добавлены при коммите. Я не уверен, как это сделать.

Может ли кто-нибудь объяснить это немного лучше, и, возможно, даже небольшой пример, если это возможно?

Спасибо.

Ответы [ 4 ]

4 голосов
/ 27 сентября 2011

UnitOfWork - это инфраструктурный шаблон, который уже реализован ORM, как и Identity Map .Вам не нужно изобретать велосипед. Репозиторий , с другой стороны, является частью модели вашего домена.Репозиторий и UnitOfWork работают на различных уровнях .UnitOfWork не нужно вызывать Repository, потому что он не знает, что такое Repository.Это касается разных абстракций.Он имеет встроенный кэш сущностей и знает, в каком состоянии находятся эти сущности. Однако UnitOfWork может быть введен в репозиторий.

Правильная реализация UnitOfWork, IdentityMap, Отслеживание изменений, Ленивая загрузка утомительна.Вы действительно должны использовать существующий ORM в качестве слоя инфраструктуры, который поможет вам сосредоточиться на том, что важно - домене.

0 голосов
/ 25 сентября 2011

Одним из наиболее распространенных способов решения этой проблемы является использование инверсии управления.

Например, у вас есть классы User и Comment, и вы реализовали общий репозиторий IRepository<TDomainObject>.Это значит, что хранилище User или Comment просто задает параметр TDomainObject:

  • IRepository<User>
  • IRepository<Comment>

Позже вы настроиликто реализует IRepository<User> и IRepository<Comment>, поэтому, если вы используете что-то вроде Общего локатора служб Microsoft Pattern & Practices, и мы находимся в теле метода commit в вашей единице работы :

foreach(DomainObject some in NewObjects)
{
        ((IRepository<DomainObject>)ServiceLocator.Current.GetInstance(Type.GetType(string.Format("NamespacesToGenericRepository.IRepository`1[[{0}]]", some.GetType().FullName)))).Add(some); 
}

Примечание IRepository<TDomainObject> имеет контравариантный TDomainObject универсальный параметр, тип которого должен наследовать базовый тип объекта домена, называемый DomainObject , который разрешаетupcast-что-то вроде IRepository<User> до IRepository<DomainObject>.

Другими словами, ваша IRepository<TDomainObject> подпись интерфейса будет выглядеть следующим образом:

public interface IRepository<out TDomainObject>
    where TDomainObject : DomainObject

Это просто сводка и / илиподсказка о том, как реализовать размещение конкретного репозитория, чтобы единица работы объектов домена могла управлять объектами любого специализированного объекта домена.

Если вы хотите узнать больше о инверсииконтрольная проверкаэта статья в Википедии:

И, исходя из собственного опыта, я хотел бы предложить вам Виндзорский замок как инверсия контроля рамки выбора:

0 голосов
/ 26 сентября 2011

У вас есть несколько подходов:

  1. Отслеживание изменений путем создания класса UnitOfWork, который хранит изменения в памяти до тех пор, пока вы не запросите фиксацию, реализация может быть: RegisterAdd (entity), RegisterDelete (entity), RegisterUpdate (entity), .... затем Commit ();который будет перебирать все зарегистрированные изменения и фиксировать.(http://msdn.microsoft.com/en-us/magazine/dd882510.aspx)
  2. Вы можете использовать TransactionScope в качестве распределенной транзакции для группировки всех обновлений и фиксации в конце единицы работы. ( как реализовать единицу работы, используя только TransactionScope и sqlconnections )
0 голосов
/ 25 сентября 2011

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

Изменение состоянийможет включать Новый, Измененный и Удаленный.

проверьте эту ссылку для получения дополнительной информации.

Это может помочь использовать реализацию этого, чтобы получить лучшую идею.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...