让Dapper在一个项目中支持多种库
dotNET跨平台
以下文章来源于桂迹 ,作者桂素伟
如果想在一个项目中,用DapperPlus支持多种数据库该怎么做?
在《让Dapper支持Mock》中我们定义了DapperPlus,可以基于这个类,实现两个子类:MySqlDapperPlus,MsSqlDapperPls,在这两个子类的构造中适配对应的数据库类型,从注放容器中,获取IDbConnection实例,根据实例的类型来选取配置中的对应连接字符串,这里用到的是根据数据类型来配置,也是一种约定。
MySqlDapperPlus.cs
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace WebDemo01.Services
{
public class MySqlDapperPlus : DapperPlus
{
public MySqlDapperPlus(IEnumerable<IDbConnection> connections, IConfiguration configuration)
{
var connectionStrings = configuration.GetSection("ConnectionStrings").Get<Dictionary<string, string>>();
_connection = connections.FirstOrDefault(c => c.GetType().Name == "MySqlConnection");
_connection.ConnectionString = connectionStrings.Where(s => s.Key.ToLower().Contains("mysql")).FirstOrDefault().Value;
}
}
}
MsSqlDapperPlus.cs
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace WebDemo01.Services
{
public class MsSqlDapperPlus : DapperPlus
{
public MsSqlDapperPlus(IEnumerable<IDbConnection> connections, IConfiguration configuration)
{
var connectionStrings = configuration.GetSection("ConnectionStrings").Get<Dictionary<string, string>>();
_connection = connections.FirstOrDefault(c => c.GetType().Name == "SqlConnection");
_connection.ConnectionString = connectionStrings.Where(s => s.Key.ToLower().Contains("mssql")).FirstOrDefault().Value;
}
}
}
这时,会有问题,DapperPlus没有无参构造,_connection访问级别也太低,所以要改造一下DapperPlus。
/// <summary> /// DappePlusr类 /// </summary> public class DapperPlus : IDapperPlus { protected IDbConnection _connection; /// <summary> /// 无参构造函数 /// </summary> public DapperPlus() { } //下面和原来的一样 }
public void ConfigureServices(IServiceCollection services){ services.AddControllers(); services.AddScoped<IDbConnection, MySqlConnection>(); services.AddScoped<IDbConnection, SqlConnection>(); services.AddScoped<IDapperPlus, MySqlDapperPlus>(); services.AddScoped<IDapperPlus, MsSqlDapperPlus>();}
appsettings.json
"ConnectionStrings": { "MySqlConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=mysql_testdb", "MsSqlConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=mssql_testdb" }
如果是多个库,还要读写分离该怎么实现?其实和不分离是一样的,要改造《让Dapper读写分离》中的DapperPlusWrite和DapperPlusRead两个类,分别增加无参构造函数,和把_connection改成protected,方便子类中参访问到。
然后定义三个类:MySqlDapperPlusRead和MsSqlDapperPlusRead继承DapperPlusRead;MySqlDapperPlusWrite和MsSqlDapperPlusWrite继承DapperPlusWrite。在四个类的构造函数中,按照自己数据库的类型,Read或Write类型来取配置文件中的连接字符串即可。
Startup.cs
public void ConfigureServices(IServiceCollection services){ services.AddControllers(); services.AddScoped<IDbConnection, MySqlConnection>(); services.AddScoped<IDbConnection, SqlConnection>(); services.AddScoped<IDapperPlusRead, MySqlDapperPlusRead>(); services.AddScoped<IDapperPlusRead, MsSqlDapperPlusRead>(); services.AddScoped<IDapperPlusWrite, MySqlDapperPlusWrite>(); services.AddScoped<IDapperPlusWrite, MsSqlDapperPlusWrite>();}
appsettings.json
"ConnectionStrings": { "MySqlReadConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=read_mysql_testdb", "MySqlWriteConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=write_mysql_testdb", "MsSqlReadConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=read_mssql_testdb", "MsSqlWriteConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=write_mssql_testdb" }
最后,在业务的Service中,读有两个,按类型区分,写有两个,按类型区分,代码如下:
public class GoodsService : IGoodsService
{
private readonly IDapperPlusWrite _mySqlDapperWrite;
private readonly IDapperPlusWrite _msSqlDapperWrite;
private readonly IDapperPlusRead _mySqlDapperRead;
private readonly IDapperPlusRead _msSqlDapperRead;
public ShopService(IEnumerable<IDapperPlusWrite> dapperWrites, IEnumerable<IDapperPlusRead> dapperReads)
{
foreach (var dapperWrite in dapperWrites)
{
switch (dapperWrite)
{
case MySqlDapperPlusWrite mySqlDapperPlusWrite:
_mySqlDapperWrite = mySqlDapperPlusWrite;
break;
case MsSqlDapperPlusWrite msSqlDapperPlusWrite:
_msSqlDapperWrite = msSqlDapperPlusWrite;
break;
}
}
foreach (var dapperRead in dapperReads)
{
switch (dapperRead)
{
case MySqlDapperPlusRead mySqlDapperPlusRead:
_mySqlDapperRead = mySqlDapperPlusRead;
break;
case MsSqlDapperPlusRead msSqlDapperPlusRead:
_msSqlDapperRead = msSqlDapperPlusRead;
break;
}
}
}
}
赞 (0)