Проблемы с образцом репозитория EF4 при внедрении репозитория в сервис. - PullRequest
2 голосов
/ 13 декабря 2010

Мне трудно протестировать EntityFramework 4. Я использую его с использованием подхода, основанного на базе данных, слишком поздно, чтобы перейти к poco. Нужно доставлять довольно быстро, нет времени на то, чтобы научиться как обычно.

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

  1. Чтобы внедрить репозиторий в службу (конструктор), вызывающему уровню необходимо иметь ссылку на DAL (объекты EF). Я не хочу этого

  2. Если у меня много репозиториев, например, CustomerRepository, EmployeeRepository, то мне нужно столько конструкторов, сколько репозиториев, чтобы я мог внедрить репозиторий.

    3. Не уверен, куда идти отсюда. Я не нашел ни одного примера в сети, где они вводят репозиторий в сервис, используя EF4. Все примеры, которые я видел, издеваются над хранилищем сами по себе, что нехорошо для меня.

Мне нужно протестировать свой сервисный уровень / BizLayer, не обращаясь к базе данных.

Все это просто не поддается тестированию и добавляет так много зависимостей и проблем.

Прикольный пример, который я собрал

public class DepartmentServiceLibrary
{
    private readonly IDepartmentRepository _departmentRepository;

    public DepartmentServiceLibrary(IDepartmentRepository  departmentRepository)
    {
        _departmentRepository = departmentRepository;
    }

    public List<DepartmentDto> GetDepartments()
    {
        return DeparmentBiz.GetDepartments();
    }

    private DeparmentBL _departmentBiz;
    private DeparmentBL DeparmentBiz
    {
        get
        {
            return _departmentBiz ?? new DeparmentBL(_departmentRepository);
        }
    }
}

// внутренний класс

internal class DeparmentBL
{
    private readonly IDepartmentRepository _departmentRepository;

    public DeparmentBL(IDepartmentRepository departmentRepository)
    {
        _departmentRepository = departmentRepository;
    }

    public List<DepartmentDto> GetDepartments()
    {
        using (var ctx = new AdventureWorksContext())
        {
            var uow = new UnitOfWork(ctx);
            _departmentRepository.UnitOfWork = uow;
            var query = _departmentRepository.GetAll();

            return query.Select(dpt => new DepartmentDto
                                           {
                                               DepartmentId = dpt.DepartmentID,
                                               Name = dpt.Name,
                                               GroupName = dpt.GroupName
                                           }).ToList();
        }
    }
}

Следующий TestMethod требует, чтобы я добавил в dal ссылку, которая побеждает точку

    [TestMethod]
    public void Should_be_able_to_call_get_departments()
    {
        var mock = new Mock<IDepartmentRepository>();
        var expectedResult = new List<Department>();  //Dependency to DAL as Department is a EF Entity generated by EF.

        mock.Setup(x => x.GetAll()).Returns(expectedResult);
        var companyService = new MyCompanyBL(mock.Object);  //InternalVisibileTO
        var departments = companyService.GetAll();
        //assert removed for brevity

Есть предложения или примеры, показывающие, как это сделать? спасибо

    }

Ответы [ 2 ]

1 голос
/ 13 декабря 2010

Краткий ответ: поскольку вы не используете POCO, все ваши слои будут иметь ссылку на ваш DAL.

Без POCO вы используете генерацию кода, что означает, что EF создает классы модели в файле Model.edmx.designer.cs.

Опция (еще не пробовал - с головы до ног) - вручную проецировать объекты EF в DTO.

Итак, ваш репозиторий может сделать это:

public List<OrderDTO> GetOrdersForCustomer(int customerId)
{
   return _ctx.Orders
        .Where(x => x.CustomerId == customerId)
        .ToList()
        .Select(x => new OrderDTO { // left to right copy });
}

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

Но здесь вы проецируете на классы повсюду (в основном это POCO, но вручную и с большим количеством работы) копирование свойств слева направо - очень болезненно.

Однако это вариант.

Честно говоря - это не займет много времени , чтобы перейти к POCO.

Существует шаблон T4, который сгенерирует POCO для вас - вы можете начать работу в считанные минуты.

И поскольку вы уже используете внедрение зависимостей и репозиторий, вы должны либо откусить маркер и перейти на POCO, либо сохранить ссылку на DAL.

0 голосов
/ 12 августа 2017

Нечто похожее с точки зрения кода можно увидеть здесь в GitHub и подробное объяснение можно найти в TechNet

...