Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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# 什么是IRepository?它的用途是什么?_C#_Asp.net Mvc_Vb.net - Fatal编程技术网

C# 什么是IRepository?它的用途是什么?

C# 什么是IRepository?它的用途是什么?,c#,asp.net-mvc,vb.net,C#,Asp.net Mvc,Vb.net,什么是IRepository?为什么要使用它,简单明了的例子不会有什么坏处。IRepository不是.Net framework中定义的类型。通常,当您看到一个名为that的接口时,程序使用Repository模式()。通常,当人们使用这种模式时,他们会创建一个所有存储库都遵循的接口。这样做有很多好处。其中一些好处是代码解耦和单元测试 这样做也很常见,这样就可以利用IoC()。当您想要实现存储库模式时,IRepository是您指定的接口。正如@Brian Ball所说,它不是.NET的一部分

什么是IRepository?为什么要使用它,简单明了的例子不会有什么坏处。

IRepository
不是.Net framework中定义的类型。通常,当您看到一个名为that的接口时,程序使用Repository模式()。通常,当人们使用这种模式时,他们会创建一个所有存储库都遵循的接口。这样做有很多好处。其中一些好处是代码解耦和单元测试


这样做也很常见,这样就可以利用IoC()。当您想要实现存储库模式时,
IRepository
是您指定的接口。正如@Brian Ball所说,它不是.NET的一部分,而是您创建的一个接口

使用存储库模式的开发人员广泛建议使用接口来实现。例如,在我现在开发的应用程序中,我有5个存储库。4个特定的和1个通用的。每一个都继承了一个
IRepository
,这确保了我不会因为实现上的差异而出现问题

至于代码示例,我将尝试:

interface IRepository<T> where T : class {
    IQueryable<T> Select();
}
接口i假设,其中T:class{
IQueryable Select();
}
作为通用存储库实现:

public class Repository<T> : IRepository<T> where T : class {
    public IQueryable<T> Select() {
        return this.ObjectContext.CreateObjectSet<T>();
    }
}
public class EmployeeRepository : IRepository<Employee> {
    public IQueryable<Employee> Select() {
        return this.ObjectContext.Employees;
    }
}
公共类存储库:IRepository,其中T:class{
公共IQueryable Select(){
返回此.ObjectContext.CreateObjectSet();
}
}
作为专用存储库实施:

public class Repository<T> : IRepository<T> where T : class {
    public IQueryable<T> Select() {
        return this.ObjectContext.CreateObjectSet<T>();
    }
}
public class EmployeeRepository : IRepository<Employee> {
    public IQueryable<Employee> Select() {
        return this.ObjectContext.Employees;
    }
}
公共类EmployeeRepository:IRepository{
公共IQueryable Select(){
返回this.ObjectContext.Employees;
}
}
Repository
EmployeeRepository
都实现了
IRepository
,但是它们执行查询的方式略有不同。通用存储库必须先创建一个T对象集,然后才能尝试执行任何操作

请记住,
Repository
应该锁定到接口,在接口中as
EmployeeRepository
可以实现更专门的方法来完成更复杂的逻辑


我希望这能对您有所帮助。

MVC促进了关注点的分离,但这并不局限于MVC级别

数据访问本身就是一个问题。它应该在MVC的M位(即模型)中完成。你如何构建你的模型取决于你,但人们通常遵循经过尝试和测试的模式(为什么要重新发明轮子?)。存储库模式是当前的标准。但是,不要期望一个简单的公式,因为几乎所有的开发人员都有不同的变化

IRepository只是您创建的一个接口(它不是MVC、ASP.NET或.NET的一部分)。它允许您将存储库与实际实现“解耦”。解耦很好,因为它意味着您的代码…:

  • 您的代码更易于重用。这真是太好了
  • 您的代码可以使用控制反转(或依赖项注入)。这有助于将您的关注点很好地分开。它特别好,因为它允许单元测试
  • 您的代码可以进行单元测试。这在具有复杂算法的大型项目中尤其适用。它在任何地方都是好的,因为它增加了您对正在使用的技术以及您试图在软件中建模的领域的理解
  • 您的代码将围绕最佳实践构建,遵循一种通用模式。这很好,因为它使维护更加容易
  • 因此,在向您介绍了解耦之后,您的问题的答案是IRepository是您创建的一个接口,您可以让您的存储库从中继承。它为您提供了一个可靠的类层次结构

    我通常使用通用的IRepository:

    public class Repository<T> : IRepository<T> where T : class {
        public IQueryable<T> Select() {
            return this.ObjectContext.CreateObjectSet<T>();
        }
    }
    
    public class EmployeeRepository : IRepository<Employee> {
        public IQueryable<Employee> Select() {
            return this.ObjectContext.Employees;
        }
    }
    
    间接的

    在这里,张力是一个实体。我使用的代码是:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Wingspan.Web.Mvc
    {
        public interface IRepository<TEntity> where TEntity : class
        {
            List<TEntity> FetchAll();
            IQueryable<TEntity> Query {get;}
            void Add(TEntity entity);
            void Delete(TEntity entity);
            void Save();
        }
    }
    
    现在在我的控制器中,我可以写:

    MyService.DeleteUserCourse(5);
    MyService.Save();
    
    有了这种模式,你的应用程序的开发就更像是一条生产线,最终形成了一个非常简单的控制器。装配线的每一个部件都可以独立于其他任何部件进行测试,因此缺陷被消灭在萌芽状态

    如果这是一个冗长而笨拙的答案,那是因为真正的答案是:

    购买并学会在MVC中思考。

    存储库是一种抽象,它表示任何底层和任意数据存储,就好像它是内存中的对象集合一样

    由于常规做法和系统限制,此定义被变形为更实用的形式,即内存中的对象集合,表示一些底层和任意的数据存储,可能是断开连接的数据存储。在引擎盖下,存储库可以链接到数据库、平面文件、内存中的对象集合,或者任何您可以想象的东西。存储库的用户不在乎

    因此,
    IRepository
    是定义Api代码希望客户端代码如何与存储库交互的接口契约。这通常包括添加、更新、删除和获取合同,例如,这是一个非常常见的存储库合同示例:

    public interface IRepository<TEntity> where TEntity : class
    {
        List<TEntity> GetAll();
        void Add(TEntity entity);
        void Delete(TEntity entity);
        void Save();
    }
    
    如果为所有实体定义一个基类,我们将其称为
    DomainObject
    ,并为其指定一个
    Id
    字段,则可以执行以下操作:

    public interface IRepository<TEntity> where TEntity : DomainObject
    {
        TEntity GetById(object Id);
    
        List<TEntity> GetAll();
        List<TEntity> Get(Func<TEntity, bool> where);
        void Insert(TEntity entity);
        void Insert(IEnumerable<TEntity> entities);
        void Remove(TEntity entity);
        void Remove(IEnumerable<TEntity> entities);
    
        void SyncDisconnected(TEntity entity, bool forDeletion = false);
        void SyncDisconnected(IEnumerable<TEntity> entities, bool forDeletion = false);
    }
    
    需要执行此操作的原因是,在大多数情况下,同步断开连接的对象以进行删除与同步断开连接的对象以进行添加或修改不兼容。(试一试。你会发现针对存储的删除要求与添加或修改的要求相差很大)。因此,接口应该定义一个契约,以便实现能够区分两者


    您可以针对任何基础数据存储的任何存储库(连接或断开连接)实现此接口,包括对基础数据存储的其他抽象,如Entity Framework。

    我知道这听起来可能有点宽泛,但有人能介绍一下基本知识吗。
        void SyncDisconnectedForDeletion(TEntity entity);