【问题标题】:EF4 Repository Pattern problems injecting repository into service .Cannot seem to get it rightEF4 存储库模式问题将存储库注入服务。似乎无法正确处理
【发布时间】:2018-12-31 21:14:31
【问题描述】:

我发现很难测试 EntityFramework 4。我使用的是数据库优先方法,现在转移到 poco 为时已晚。需要快速交付,没有时间像往常一样正确学习。

我已经使用工作单元实现了存储库模式,但是我发现很难将存储库注入到我的服务层中,以便我可以测试我的业务层服务的行为、验证等......而无需访问数据库。 但是我遇到了很多小问题。

  1. 为了将存储库注入服务(构造函数),调用层需要引用 DAL(EF 实体)。我不要这个

  2. 如果我有很多存储库 EG 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

有什么建议或例子可以说明如何做到这一点吗? 谢谢

    }

【问题讨论】:

    标签: entity-framework-4 moq repository-pattern


    【解决方案1】:

    简短的回答是 - 由于您没有使用 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 的引用。

    【讨论】:

    • 刚刚证实了我的恐惧。我需要学习 t4。我所做的一切我都必须能够解释。我会试一试
    • 使用 poco 我想你转而使用代码生成并使用 t4 模板。存储过程、复杂类型等怎么样。如何在 poco 中处理它们。你生成它们吗?
    • @user231465 - 这里是 T4 POCO 生成器:visualstudiogallery.msdn.microsoft.com/en-us/…。您不需要“学习” T4 本身。只需安装它,让它生成您的 POCO - 并将生成的 POCO 移动到单独的程序集中。
    • 是的,您仍然可以创建存储过程,复杂类型。我发现的唯一问题是您不能“生成”复杂类型。您必须手动创建它们 - 没什么大不了的。也许也有一个模板。
    • 顺便说一句 - 我在我当前的项目中使用存储库、DI、EF4、POCO、SPROC。一切正常 - 所以请放心,人们已经这样做了,而且工作正常。
    【解决方案2】:

    可以在GitHub 中看到类似代码的内容 详细解释见TechNet

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2018-03-09
      相关资源
      最近更新 更多