泛型仓储+服务架构落地

发布时间 2023-12-26 14:53:18作者: HenryBest

一、前言

本文章只为作学习记录使用,文中图片或引用均为网上摘抄,如涉嫌侵权请联系本人删除。

二、准备工作

1.Visual Studio 2022

2.Windows 11、.NET 6 环境

三、什么是仓储

仓储(Repository)模式自2004年首次作为领域驱动模型DDD设计的一部分引入,仓储本质上是提供提供数据的抽象,以便应用程序可以使用具有接口的相似的简单抽象集合。从此集合中CURD是通过一些列直接的方法完成,无需处理连接、命令等问题,使用此种模式可帮助实现松耦合,并保持领域对象的持久性无知。

  • 仓储模式是为了在程序的数据访问层和业务逻辑层之间创建的一个抽象层
  • 仓储模式是一种数据访问模式,提供一种更松散耦合的数据访问方法
  • 将创建数据访问的逻辑写在单独的类中即仓储
  • 仓储负责和业务层进行持久化通信

仓储(Repository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装。其优点是

  • 业务层无需知道具体实现达到分离关注点
  • 提高对数据库访问的维护,对于仓储的改变并不改变业务的逻辑。

 

那么什么是泛型仓储呢?

在开发中,我们经常需要与数据库进行交互,进行数据的增删改查操作。这个过程可以通过使用Entity Framework (EF)来简化。EF是一个强大的对象关系映射(ORM)框架,它允许我们以面向对象的方式操作数据库。

在编写数据访问层代码时,我们经常会遇到一些重复的操作,比如增删改查的基本操作。为了提高代码的复用性和减少冗余,我们可以引入泛型仓储模式。

泛型仓储模式是一种常见的设计模式,它将数据访问层的常见操作进行了抽象和封装,通过泛型参数来实现对不同实体类型的操作,实现了代码的复用性和可扩展性。

在EF中,我们可以利用泛型仓储模式来封装常见的CRUD(Create, Read, Update, Delete)操作,使我们的数据访问层更加简洁和高效。

如下代码便实现了一个简单的泛型接口

 public interface IRepository<TEntity,Tvo> where TEntity : class
 {
     Task<List<TEntity>> Query();
 }

仓储实现

public class Repository<TEntity, Tvo> : IRepository<TEntity,Tvo> where TEntity : class,new()
{
    public async Task<List<TEntity>> Query()
    {
        await  Task.CompletedTask; //此处应为数据库查询,本次只做简单演示
        return new List<TEntity>();
    }
}

四、项目结构

Common层:主要是一些底层的工具类,公共方法等等。无引用项目

Host层:项目入口层,引用Sevice层

IService层:业务接口层,引用Model层

Model层:实体类存储,引用Common层

Repository:泛型仓储层,数据库交互,引用Model层

Service层:为业务接口的实现层,引用IService层和Repository层

五、案例代码

1.Model实体

 public class User
 {
     public int Id { get; set; }
     public string Name { get; set; }
 }

2.泛型仓储以及实现

public interface IRepository<TEntity,Tvo> where TEntity : class
{
    Task<List<TEntity>> Query();
}
public class Repository<TEntity, Tvo> : IRepository<TEntity,Tvo> where TEntity : class,new()
{
    public async Task<List<TEntity>> Query()
    {
        await  Task.CompletedTask; //此方法代码应为数据库查询,本次只做简单演示,此行代码是为了 async不进行报错。
        return new List<TEntity>();
    }
}

3.业务接口

public interface IService<TEntity>where TEntity : class
{
    Task<List<TEntity>> Query();
}

4.实现业务接口

public class Service<T,Tvo>: IService.IService<T, Tvo> where T : class,new()
{
    public async Task<List<T>> Query()
    {
        var BaseRepository = new Repository.Repository<T, Tvo>();
        return await BaseRepository.Query();
    }
}

Tvo:后续可能作为数据传输对象使用,此处并未使用。

5.Host 控制器代码

[HttpGet(Name = "GetUserList")]
public async Task<List<User>> Get()
{
 var UserService = new Service.Service<User, UserVo>();//后期使用依赖注入实现,本次只做演示
 return await UserService.Query();
}

六、总结

1.通过使用.NET EF泛型仓储模式,我们可以提高代码的复用性和可维护性。

2.泛型仓储模式将数据访问层的常见操作进行了封装,使我们可以更加专注于业务逻辑的处理,而无需关注底层的数据库操作。

3.当需要创建新的数据访问层时,我们只需要实现。

4.学习并非一日之功,多写多看多练。

async