为什么在使用实体框架实现存储库模式时使用接口?

Rya*_*yan 2 c# entity-framework repository-pattern

在实现存储库模式时,结合实体框架,为什么我会在其存储库类中看到许多使用接口的示例?这里参考的具体例子.

界面有什么意义?为什么不只是上课?例如,对于员工来说,是否真的需要多个订阅该特定接口的类?

Ale*_*dro 5

它是一种经常使用的模式,通常专门用于单元测试,并非真正特定于实体框架,存储库模式,甚至任何数据访问类型.另一个很大的好处是,它为后者提供了提供替代实现的机会,而无需使用它来更改代码.例如,考虑使用依赖注入模式的此代码:

public class EmployeeService
{
    private readonly IEmployeeRepository employeeRepository;

    public EmployeeService(IEmployeeRepository employeeRepository)
    {
        this.employeeRepository=employeeRepository;
    }

    public IEnumerable<Employee> GetAllEmployees()
    {
        IEnumerable<Employee> employeeList=this.employeeRepository.GetAll();
        //Optionally do some processing here
        return employeeList;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过在存储库中创建接口,请注意您现在可以完全使用该接口,而无需提及实际存储库,这是它的真正价值.它主要有两个好处:

  • 如果你想为这个类编写一个自动单元测试,你可以给它一个虚假的实现IEmployeeRepository,它不会转到真正的数据库,而是返回一个硬编码列表,这样你就可以测试你的方法而不用担心DB现在.这称为"模拟",通常是将接口放在那里的主要原因.还有一些库可以自动化该过程,所有这些库都依赖于它们生成实现接口的假类的事实.到目前为止,这是建立这样的界面的最常见原因.
  • 您可能决定将来某个时候想要用其他东西替换实体框架,或者说,想要将存储库实现为与关系数据库不同的东西.在这种情况下,您将编写另一个存储库,实现完全相同的接口,但执行完全不同的操作.鉴于使用它的服务仅依赖于接口,只要同一合同得到尊重,代码将完全不受修改(当然,实际创建repo并将其提供给服务的代码必须更改,但这是另一个历史记录) .这样,无论在何处读取/保存数据,相同的服务都可以正常工作.

  • 我的心已经被吹了一夜了。谢谢你。 (2认同)
  • 在这些情况下,您可以向接口和实现类添加任何必需的方法。将它添加为非接口方法,即使是公共方法,也会使接口的好处无效,因为您将不再能够仅使用接口调用它,从而迫使用户耦合到类而不是接口。出于与您相同的原因,我不喜欢在公共接口中使用谓词,之后测试它们有点复杂,所以我避免使用这些,除非我想做一些非常通用的事情。然而,在内部实现中使用它们是完全可以的。 (2认同)