Зачем использовать шаблон хранилища или объяснить его мне?

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

Высказывание

• Скрыть EF от верхнего слоя
• Сделать код более надежным

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

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

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

  • Свободная связь (чтобы скрыть EF от верхнего слоя?)
  • Избегайте повторного написания той же инструкции LINQ для того же запроса

Я правильно понимаю это?

Если я пишу DataAccessLayer, который является классом, имеют методы

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

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

AddBarObject(Bar obj)
{
...
}

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

Объяснение для манекена будет большим:)

Ответ 1

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

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

Ответ 2

Я не думаю, что вам следует.

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, то я не думаю, что он нам вообще нужен.

Ответ 3

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

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

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

Здесь есть несколько видео с приятным объяснением.

Ответ 4

Эта фотография позволяет легко понять

введите описание изображения здесь

Ответ 5

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

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

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

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

Ответ 6

По той же причине вы не делаете жестких путей к файлу кода в своем приложении: свободная связь и encapsulation. Представьте себе приложение с жестко закодированными ссылками на "c:\windows\fonts" и проблемы, которые могут возникнуть. Вы не должны жестко ссылаться на ссылки на пути, поэтому почему вы должны ссылаться на свой уровень персистентности? Скрывайте свои пути за настройками конфигурации (или специальные папки или независимо от того, что поддерживает os) и скрыть вашу постоянство за репозиторием. Это будет намного проще unit test, развертывание в других средах, реализация swap и причина ваших объектов домена, если проблемы сохранения сохраняются за репозиторием.

Ответ 7

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

  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();
  }
}

Ответ 8

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

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

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