Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在使用实体框架实现存储库模式时使用接口?_C#_Entity Framework_Repository Pattern - Fatal编程技术网

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

C# 为什么在使用实体框架实现存储库模式时使用接口?,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,在结合实体框架实现存储库模式时,为什么我看到许多示例使用存储库类的接口?这方面引用的一个具体示例是 界面的意义是什么?为什么不只是上课?是否真的需要不止一个类订阅这个非常特定的接口,例如,仅针对员工?这是一个常用的模式,通常专门用于单元测试,而不是实体框架、存储库模式,甚至任何数据访问类型。另一个巨大的好处是,它使后者有机会提供一个替代的实现,而无需更改使用它的代码。 例如,考虑使用模式:的代码。 公共类员工服务 { 私人只读雇员储蓄所雇员储蓄所; 公共雇员服务(IEEmployeeReposi

在结合实体框架实现存储库模式时,为什么我看到许多示例使用存储库类的接口?这方面引用的一个具体示例是


界面的意义是什么?为什么不只是上课?是否真的需要不止一个类订阅这个非常特定的接口,例如,仅针对员工?

这是一个常用的模式,通常专门用于单元测试,而不是实体框架、存储库模式,甚至任何数据访问类型。另一个巨大的好处是,它使后者有机会提供一个替代的实现,而无需更改使用它的代码。 例如,考虑使用模式:

的代码。
公共类员工服务
{
私人只读雇员储蓄所雇员储蓄所;
公共雇员服务(IEEmployeeRepository employeeRepository)
{
this.employeeRepository=employeeRepository;
}
公共IEnumerable GetAllEmployees()
{
IEnumerable employeeList=this.employeeRepository.GetAll();
//也可以在这里进行一些处理
返回员工名单;
}
}
通过将接口放在存储库中,请注意,您现在可以完全使用该接口工作,而不必提及实际的存储库,这才是它的真正价值所在。它主要有两个好处:

  • 如果你想为这个类编写一个自动单元测试,你可以给它一个
    IEmployeeRepository
    的假实现,它不会进入真实的数据库,而是返回一个硬编码的列表,这样你就可以测试你的方法而不用担心数据库了。这被称为“Mock”,通常是将该接口放在那里的主要原因。还有几个库可以自动化这个过程,它们都依赖于生成一个实现接口的假类这一事实。到目前为止,这是放置这样一个接口的最常见原因
  • 您可能会在将来的某个时候决定用其他东西替换实体框架,或者,比方说,要实现一个与关系数据库不同的存储库。在本例中,您将编写另一个存储库,实现完全相同的接口,但执行完全不同的操作。考虑到使用它的服务只依赖于接口,只要遵守相同的合同,代码将完全不受修改地工作(当然,实际创建回购并将其提供给服务的代码必须更改,但这是另一个历史)。这样,无论在何处读取/保存数据,同一服务的工作方式都是相同的

今晚我的头脑已经完全清醒了。谢谢。那么,当您需要特定的方法时,如对于帐户存储库,您可能希望按名称获取帐户,您会怎么做?您是在Where中使用谓词,还是专门为此添加其他非接口函数?我觉得允许谓词的可测试性较差。在这种情况下,您可以向接口和实现类添加任何必需的方法。将其添加为非接口方法(即使是public)将抵消接口的好处,因为您将不再能够仅使用接口调用它,从而迫使用户耦合到类而不是接口。出于与您相同的原因,我不喜欢在公共接口中使用谓词,之后测试它们会有点复杂,所以我避免使用这些谓词,除非我想做一些非常通用的事情。但是,在内部实现中使用它们是完全可以的。
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;
    }
}