Зачем использовать шаблон репозитория или, пожалуйста, объясните мне? - PullRequest
50 голосов
/ 06 января 2012

Я изучаю шаблон репозитория и читал Шаблон репозитория с Entity Framework 4.1 и Code First и Универсальный шаблон репозитория - Entity Framework, ASP.NET MVC и треугольник модульного тестирования о том, какони реализуют шаблон хранилища с помощью Entity Framework.

Говоря

• Скрыть EF из верхнего уровня
• Сделать код лучше тестируемым

Сделать кодЯ лучше понимаю, но зачем скрывать EF от верхнего уровня?

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

Я предполагаю, что для

  1. Слабая связь (поэтому скрыть EF от верхнего уровня?)
  2. Избегать повторной записи жеОператор LINQ для того же запроса

Правильно ли я понимаю?

Если я напишу DataAccessLayer, у которого есть класс, есть методы

QueryFooObject(int id)
{
..//query foo from entity framework
} 

AddFooObject(Foo obj)
{
.. //add foo to entity framework
}
......
QueryBarObject(int id)
{
..
}

AddBarObject(Bar obj)
{
...
}

Это также шаблон репозитория?

Объяснение для пустышки будет здорово:)

Ответы [ 8 ]

65 голосов
/ 16 июня 2012

Не думаю, что вы должны.

Entity Framework - это уже уровень абстракции над вашей базой данных. Контекст использует единицу работы шаблона, и каждый DBSet является хранилищем. Добавление шаблона репозитория поверх этого отдаляет вас от функций вашего ORM.

Я говорил об этом в своем блоге: http://www.nogginbox.co.uk/blog/do-we-need-the-repository-pattern

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

EF не очень хорошо тестируется "из коробки", но довольно просто сделать макетную версию контекста данных EF с интерфейсом, который можно вводить.

Я говорил об этом здесь: http://www.nogginbox.co.uk/blog/mocking-entity-framework-data-context

Если нам не нужен шаблон репозитория, чтобы сделать EF тестируемым, тогда я не думаю, что он вообще нам нужен.

7 голосов
/ 11 октября 2016

Эта картинка облегчает понимание

enter image description here

7 голосов
/ 06 января 2012

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

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

4 голосов
/ 10 января 2013

Это также преимущество, чтобы держать ваши запросы в центральном месте;в противном случае ваши запросы разбросаны и их сложнее обслуживать.

И первое, что вы упомянули: «Скрывать EF» - это хорошо!Например, сохранение логики может быть сложно реализовать.Существует несколько стратегий, которые лучше всего применяются в разных сценариях.Особенно когда речь идет о сохранении сущностей, которые также имеют изменения в связанных сущностях.

Использование репозиториев (в сочетании с UnitOfWork) также может централизовать эту логику.видео с хорошим объяснением.

3 голосов
/ 06 января 2012

Системы репозитория хороши для тестирования.

Одной из причин является то, что вы можете использовать Dependency Injection.

По сути, вы создаете интерфейс для своего репозитория, и вы ссылаетесь на интерфейс для него, когда выделают объект.Затем вы можете позже создать поддельный объект (например, с помощью moq), который реализует этот интерфейс.Используя что-то вроде ninject, вы можете привязать соответствующий тип к этому интерфейсу.Но вы просто взяли зависимость из уравнения и заменили ее чем-то проверяемым.

Идея состоит в том, чтобы иметь возможность легко менять реализации объектов для целей тестирования. Надеюсь, что это имеет смысл.

0 голосов
/ 05 мая 2017

Я знаю, что давать ответы в ответе здесь нехорошо, однако хотел бы поделиться видео, которое объясняет различные преимущества шаблона репозитория при использовании его с платформой Entity. Ниже ссылка на YouTube.

https://www.youtube.com/watch?v=rtXpYpZdOzM

В нем также приведены подробные сведения о том, как правильно реализовать шаблон репозитория.

0 голосов
/ 02 ноября 2016

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

  class StudenRepository
  {
     dbcontext ctx;
     StundentRepository(dbcontext ctx)
     {
       this.ctx=ctx;
     }
     public void EnrollCourse(int courseId)
     {
       this.ctx.Students.Add(new Course(){CourseId=courseId});
     }
  }

  class TeacherRepository
  {
     dbcontext ctx;
     TeacherRepository(dbcontext ctx)
     {
       this.ctx=ctx;
     }
     public void EngageCourse(int courseId)
     {
       this.ctx.Teachers.Add(new Course(){CourseId=courseId});
     }
  }

  public class MyunitOfWork
  {
     dbcontext ctx;
     private StudentRepository _studentRepository;
     private TeacherRepository _teacherRepository;

     public MyunitOfWork(dbcontext ctx)
     {
       this.ctx=ctx;
     }

    public StudentRepository StundetRepository
    {
       get
       {       
             if(_studentRepository==null)
                _stundentRepository=new StundetRepository(this.ctx);

            return _stundentRepository;    
       }
    }

    public TeacherRepository TeacherRepository 
    {
       get
       {       
             if(_teacherRepository==null)
                _teacherRepository=new TeacherRepository (this.ctx);

            return _teacherRepository;    
       }
    }

    public void Commit()
    {
         this.ctx.SaveChanges();
    }
  }

//some controller method
public void Register(int courseId)
{
  using(var uw=new MyunitOfWork(new context())
  {
    uw.StudentRepository.EnrollCourse(courseId);
    uw.TeacherRepository.EngageCourse(courseId);
    uw.Commit();
  }
}
0 голосов
/ 06 января 2012

По той же причине, по которой вы не кодируете пути к файлам в своем приложении: слабая связь и инкапсуляция . Представьте себе приложение с жестко закодированными ссылками на «c: \ windows \ fonts» и проблемами, которые могут вызвать. Вы не должны жестко ссылаться на ссылки на пути, так почему вы должны жестко ссылаться на свой уровень персистентности? Скройте ваши пути за настройками конфигурации (или специальные папки или все, что поддерживает ваша ОС) и скройте свое постоянство за хранилищем. Будет гораздо проще проводить модульное тестирование, развертывание в других средах, замену реализаций и анализ ваших доменных объектов, если проблемы сохранения сохраняются за хранилищем.

...