UOW и репозитории в приложении Entity Framework asp.net - PullRequest
4 голосов
/ 24 января 2012

Я только начал читать об использовании репозитория и единиц работы.В настоящее время я пытаюсь использовать его с 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.         
}

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

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

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

Ответы [ 2 ]

2 голосов
/ 24 января 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 на свой «контроллер» (возможно, код в веб-формах), потому что контроллер управляет логикой приложения и знает, какие бизнес-методы он хочет вызвать в одной единице работы.

2 голосов
/ 24 января 2012

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

public class MyBusinessService
{

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

   public void businessMethod1()
   {
   }

   public void businessMethod1()
   {
   }
}

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

...