整个过程使用了基础的泛型,抽象,继承,多态,依赖注入的相关知识,以及一丢丢的小设计,数据库选用Mysql,ORM框架选用轻量级的Dapper,对异步的查询语句进行了一次封装,使用该NuGet包的解决方案,只需要调用包下对应的方法传入参数(一般包含sql语句和实体类或参数),就可以完成增删改查的操作。
包下总共封装了七个BaseRepository方法,全部是异步的(Delete,GetOne, GetListById,Insert,SelectAsync,Update,GetByDynamicParams)。在项目中,可以使用包内的DataBaseConfig方法通过依赖注入的方式将数据库连接字符串注入整个项目,解决方案中在Startup.cs中的配置
var dataConfig = new DataBaseConfig() { ConnectionString = @"server=127.0.0.1;port=3306;database=test;userid=;password=" }; services.AddSingleton(sp => new UserDbContext(dataConfig));
新建一个DbContext类去继承包内的BaseDBContext类,通过继承父类中的数据库配置去开启Mysql的连接
public class UserDbContext: BaseDBContext { public UserDbContext(DataBaseConfig settings) : base(settings) { } }
对应包下面BaseDBContext的代码
public class BaseDBContext { private string connectionString; public IDbConnection Connection { get; set; } protected BaseDBContext(DataBaseConfig settings) { connectionString = settings.ConnectionString; Connection = new MySqlConnection(connectionString); } }
DataBaseConfig的代码
public class DataBaseConfig { public string ConnectionString { get; set; } }
目的就是拿到解决方案中的数据库连接字符串去开启包下的MySqlConnection。
在如何使用的这一步,学到最多的就是依赖注入的问题,现在回顾一下依赖注入的用法。
依赖注入就是通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用“好莱坞原则”是应用程序以被动的方式实现对流程的定制。
在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象。ASP.NET Core中的DI容器体现为一个实现了IServiceProvider接口的对象。
我们间接地通过调用IServiceCollection接口的扩展方法BuildServiceProvider得到它
IServiceCollection接口实际上代表一个元素为ServiceDescriptor对象的集合,它直接继承了另一个接口IList,而ServiceCollection类实现了该接口
体现为DI容器的ServiceProvider之所以能够根据我们给定的服务类型(一般是一个接口类型)提供一个能够开箱即用的服务实例,是因为我们预先注册了相应的服务描述信息,这些指导ServiceProvider正确实施服务提供操作的服务描述体现为如下一个ServiceDescriptor类型。
由于标准化的服务一般会定义成接口,所以在绝大部分情况下体现为一个接口类型。类型为ServiceLifetime的属性Lifetime体现了ServiceProvider针对服务实例生命周期的控制方式
ServiceDescriptor的ServiceType属性代表提供服务的生命类型,ServiceLifetime是一个枚举类型,定义其中的三个选项(Singleton、Scoped和Transient)体现三种对服务对象生命周期的控制形式。
官方推荐的构造函数注入:如果ServiceProvider试图通过调用构造函数的方式来创建服务实例,传入构造函数的所有参数必须先被初始化,最终被选择出来的构造函数必须具备一个基本的条件:ServiceProvider能够提供构造函数的所有参数。
JerryClient Sdk(NuGet)包的具体代码如下
接口类
public interface IBaseRepository<T> { Task Insert(T entity, string insertSql); Task Update(T entity, string updateSql); Task Delete(int Id, string deleteSql); Task<List<T>> SelectAsync(string selectSql); Task<T> GetOne(int Id, string selectOneSql); Task<List<T>> GetList(int Id, string selectSql); Task<List<T>> GetByDynamicParams(string sqlText, DynamicParameters dynamicParams); }
仓库实现类
using Dapper; using JerryApplication.Base; using JerryClient; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; namespace JerryApplication.BaseRepository { public class BaseRepository<T> : IBaseRepository<T> { public BaseDBContext _baseDB; public BaseRepository( BaseDBContext baseDB) { _baseDB = baseDB; } public async Task Delete(int Id, string deleteSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); await dbConnection.ExecuteAsync(deleteSql, new { Id = Id }); } } public async Task<T> GetOne(int Id, string selectOneSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); var result = await dbConnection.QueryFirstOrDefaultAsync<T>(selectOneSql, new { Id = Id }); return result; } } public async Task<List<T>> GetList(int Id, string selectSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); return await Task.Run(() => dbConnection.Query<T>(selectSql, new { Id = Id }).ToList()); } } public async Task Insert(T entity, string insertSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); await dbConnection.QueryFirstOrDefaultAsync<T>(insertSql, entity); } } public async Task<List<T>> SelectAsync(string selectSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); return await Task.Run(() => dbConnection.Query<T>(selectSql).ToList()); } } public async Task Update(T entity, string updateSql) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); await dbConnection.ExecuteAsync(updateSql, entity); } } public async Task<List<T>> GetByDynamicParams(string sqlText, DynamicParameters dynamicParams) { using (IDbConnection dbConnection = _baseDB.Connection) { dbConnection.Open(); return await Task.Run(() => dbConnection.Query<T>(sqlText, dynamicParams).ToList()); } } } }
加上之前的BaseDBContext.cs,DataBaseConfig.cs。四个类组成了整个类库。
接下来就是发布的过程
右键项目,点属性,填好信息点保存
使用打包工具将后缀名是.csproj的文件打包成后缀名为.nupkg的包
上传到nuget官网即可。
看,我昨天上传的包已经有32个下载啦,写出一个你自己的sdk,也是很有成就感的呀
项目源码的git地址为:https://github.com/zhaojiejerry/JerryClient.git