UOW и репозитории в приложении Entity Framework asp.net

Я только начал читать об использовании шаблонов репозитория и единицы работы. В настоящее время я пытаюсь использовать его с Entity Framework в приложении веб-форм asp.net. Однако у меня есть вопрос, который я не уверен, смогу ли объяснить простым способом.

Насколько я понимаю, единица работы используется для инкапсуляции бизнес-транзакции. Из примеров, которые я видел, uow используется следующим образом

 businessMethod1()
 {
    uow u = new uow(); //instantiate unit of work
    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();
    u.save(); //save the changes made to the database. (effectively saving changes made      
              //in both repository classes
 }

Теперь предположим, что у меня есть businessMethod2(), который похож на метод, описанный выше. Предположим, я хочу использовать businessMethod1() изнутри businessMethod2(), что было бы наилучшей практикой. Я хотел бы поделиться единицей работы, поэтому я должен передать ее в качестве аргумента? то есть измените метод, упомянутый выше, на

businessMethod1(uow u)
{
    bool isNew = false;
    if (u == null)
    {
        u = new uow();
        isNew = true;
    }

    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();

    if (isNew)
      u.save(); //save the changes made to the database.         
}

Это правильный способ работы с этим?

Я думал, что лучшим способом было бы использовать singleton uow. При каждом запросе страницы создается новый экземпляр uow, который используется всеми бизнес-методами. При новом запросе создается другой экземпляр. Использование singleton uow означало бы, что мне не придется передавать его ни одному из моих бизнес-методов, и в то же время я могу поделиться им ч/б со всеми своими бизнес-методами.

Есть ли недостатки в этом? Также есть ли лучший способ реализовать это?


person nighthawk457    schedule 23.01.2012    source источник
comment
Это то, чем я действительно интересовался, я никогда не видел хорошей реализации репозитория UoW, но я уверен, что они где-то есть.   -  person Not loved    schedule 24.01.2012


Ответы (2)


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

public class MyBusinessService
{

   public MyBusinessService(Repository1 repository1, Repository2, uow u)
   {
        // assign the params to fields
   }

   public void businessMethod1()
   {
   }

   public void businessMethod1()
   {
   }
}

Существует множество популярных DI-фреймворков. Выберите то, что, по вашему мнению, работает для вас.

person Eranga    schedule 24.01.2012

Речь идет об использовании UoW. Если вы помещаете использование UoW в BusinessMethod1, вы говорите, что это бизнес-абстракция высшего уровня (бизнес-фасад). Вероятно, его не следует использовать в других бизнес-операциях, потому что это нарушит его «верхний уровень». Поэтому, если вам нужно использовать логику из BusinessMethod1 в другом BusinessMethod2, это неправильный подход к добавлению логики принятия решения о существовании UoW - это нарушает разделение задач. BusinessMethod должен обрабатывать логику вашего приложения, а не создание UoW. Самое простое решение — реорганизовать ваш BusinessMethod1 и представить общие функции как новый метод без какой-либо зависимости от UoW:

public void BusinessMethod1()
{
    uow u = new uow(); 
    DoSomeWork();
    u.save(); 
}

private void DoSomeWork() 
{
    repository1 rep1 = new repository1(uow); //instantiate repository1 
    repository2 rep2 = new repository2(uow); //instantiate repository1 
    rep1.dowork();
    rep2.dowork();
}

Конечно, это всего лишь очень простой пример, потому что ваши методы по-прежнему не следуют разделению задач — они выполняют как логику, так и создание объектов. Вы должны обрабатывать UoW и создание репозиториев в другом месте и передавать созданные объекты внутрь. Вы можете использовать подход, упомянутый @Eranga, но этот рефакторинг будет по-прежнему применим, если ваш метод2 хочет вызвать что-то из метода1.

Этот подход к рефакторингу можно смоделировать также как низкоуровневые бизнес-сервисы и бизнес-фасад, но он необходим только в больших проектах. В небольших проектах вы также можете перенести взаимодействие с UoW на свой «контроллер» (вероятно, код в веб-формах), потому что контроллер управляет логикой приложения и знает, какие бизнес-методы он хочет вызывать в одной единице работы.

person Ladislav Mrnka    schedule 24.01.2012