# 创建仓储
# 首先需要建仓储接口层和仓储实现层
# 泛型仓储类如下(后续需要单独注入一次泛型仓储)
using IRepository; | |
using Microsoft.Extensions.Logging; | |
using Newtonsoft.Json; | |
using SqlSugar; | |
namespace Repository | |
{ | |
/// <summary> | |
/// 父仓储类 | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class BaseRepository<T> : SimpleClient<T>, IBaseRepository<T> where T : class, new() | |
{ | |
/// <summary> | |
/// 日志组件 | |
/// </summary> | |
private readonly ILogger _logger; | |
/// <summary> | |
/// 无日志构造函数(不需要 SQL 日志选这个) | |
/// </summary> | |
/// <param name="context"></param> | |
public BaseRepository(ISqlSugarClient context) : base(context) | |
{ | |
} | |
/// <summary> | |
/// 有日志构造函数(需要打印 SQL 选这个) | |
/// </summary> | |
/// <param name="context"></param> | |
/// <param name="logger"></param> | |
public BaseRepository(ISqlSugarClient context, ILogger logger) : base(context) | |
{ | |
base.Context = context; | |
_logger = logger; | |
base.Context.Aop.OnLogExecuting = (sql, pars) => | |
{ | |
List<Dictionary<string, object>> result = new List<Dictionary<string, object>>(); | |
foreach (var row in pars) | |
{ | |
Dictionary<string, object> value = new Dictionary<string, object>(); | |
value.Add(row.ParameterName, row.Value); | |
result.Add(value); | |
} | |
_logger.LogCritical("\r\n 【开始打印仓储日志】:\r\n 【执行时间】:{0} \r\n 【SQL执行语句】:{1} \r\n 【参数】:{2}", DateTime.Now.ToString(), sql, JsonConvert.SerializeObject(result)); | |
}; | |
// SQL 执行完 | |
base.Context.Aop.OnLogExecuted = (sql, pars) => | |
{ | |
_logger.LogCritical("\r\n 【结束打印仓储日志】:\r\n 【执行时间】:{0} \r\n 【SQL执行时间】:{1}", DateTime.Now.ToString(), base.Context.Ado.SqlExecutionTime.ToString()); | |
}; | |
} | |
/// <summary> | |
/// 分页方法(公共方法) | |
/// </summary> | |
/// <param name="PageNow"> 当前页 </param> | |
/// <param name="PageSize"> 每页个数 </param> | |
/// <returns></returns> | |
public List<T> ToPageList(int PageNow, int PageSize) | |
{ | |
return base.Context.Queryable<T>().Skip(PageSize * (PageNow - 1)).Take(PageSize).ToList(); | |
} | |
} | |
} |
# 在这里把 SqlSugarClient 拿到了,并且继承了仓储接口,和官方文档有所差异
using IRepository.DI; | |
using SqlSugar; | |
namespace IRepository | |
{ | |
/// <summary> | |
/// 父仓储接口 | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public interface IBaseRepository<T> : ISimpleClient<T>, IScoped where T : class, new() | |
{ | |
/// <summary> | |
/// 分页方法(公共方法) | |
/// </summary> | |
/// <param name="PageNow"> 当前页 </param> | |
/// <param name="PageSize"> 每页个数 </param> | |
/// <returns></returns> | |
List<T> ToPageList(int PageNow, int PageSize); | |
} | |
} |
# 注入仓储
# 继承 IScoped 接口完成自动注入
# 同样需要一个单独的注入方法,根据命名空间来注入对应的接口和类
public static IServiceCollection AddRepository(this IServiceCollection services) | |
{ | |
// 注入泛型仓储 | |
services.AddScoped(typeof(Repository.BaseRepository<>)); | |
var singletonType = typeof(IRepository.DI.ISingleton); // 单例 | |
var transientType = typeof(IRepository.DI.ITransient); // 瞬时 | |
var scopedType = typeof(IRepository.DI.IScoped); // 作用域 | |
// 获取实现了三个生命周期接口的程序集 | |
var allTypes = AppDomain.CurrentDomain.GetAssemblies() | |
.SelectMany(a => a.GetTypes().Where(t => | |
t.GetInterfaces().Contains(transientType) || | |
t.GetInterfaces().Contains(singletonType) || | |
t.GetInterfaces().Contains(scopedType))); | |
//class 的程序集 | |
var implementTypes = allTypes.Where(x => x.IsClass).ToArray(); | |
// 接口的程序集 | |
var interfaceTypes = allTypes.Where(x => x.IsInterface).ToArray(); | |
foreach (var implementType in implementTypes) | |
{ | |
var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType)); | |
//class 有接口,用接口注入 | |
if (interfaceType != null) | |
{ | |
// 判断用什么方式注入 | |
if (interfaceType.GetInterfaces().Contains(singletonType)) | |
{ | |
// 单例 | |
services.AddSingleton(interfaceType, implementType); | |
} | |
else if (interfaceType.GetInterfaces().Contains(transientType)) | |
{ | |
// 瞬时 | |
services.AddTransient(interfaceType, implementType); | |
} | |
else if (interfaceType.GetInterfaces().Contains(scopedType)) | |
{ | |
// 作用域 | |
services.AddScoped(interfaceType, implementType); | |
} | |
} | |
else //class 没有接口,直接注入 class | |
{ | |
// 判断用什么方式注入 | |
if (implementType.GetInterfaces().Contains(singletonType)) | |
{ | |
// 单例 | |
services.AddSingleton(implementType); | |
} | |
else if (implementType.GetInterfaces().Contains(transientType)) | |
{ | |
// 瞬时 | |
services.AddTransient(implementType); | |
} | |
else if (implementType.GetInterfaces().Contains(scopedType)) | |
{ | |
// 作用域 | |
services.AddScoped(implementType); | |
} | |
} | |
} | |
return services; | |
} |
# Program 类注入这个方法
builder.Services.AddRepository(); |
# 使用仓储
# 创建一个菜单仓储接口继承自 IBaseRepository
using DataModel.Table; | |
using IRepository.DI; | |
namespace IRepository | |
{ | |
/// <summary> | |
/// 菜单仓储接口 | |
/// </summary> | |
public interface IMenuRepository : IBaseRepository<MenuInfo> | |
{ | |
/// <summary> | |
/// 扩展方法(私有方法) | |
/// </summary> | |
/// <returns></returns> | |
string Test(); | |
} | |
} |
# 创建一个菜单仓储实现类,继承泛型仓储和菜单仓储接口
# 可以通过以下两个构造函数实现 SQL 日志的打印,这边选择需要日志
using DataModel.Table; | |
using IRepository; | |
using Microsoft.Extensions.Logging; | |
using SqlSugar; | |
namespace Repository | |
{ | |
/// <summary> | |
/// 菜单仓储类 | |
/// </summary> | |
public class MenuRepository : BaseRepository<MenuInfo>, IMenuRepository | |
{ | |
/// <summary> | |
/// 无日志构造函数(不需要日志就放开注释) | |
/// </summary> | |
/// <param name="context"></param> | |
// public MenuRepository(ISqlSugarClient context) : base(context) | |
// { | |
// base.Context = context; | |
// } | |
/// <summary> | |
/// 有日志构造函数(需要日志就放开注释) | |
/// </summary> | |
/// <param name="context"></param> | |
/// <param name="logger"></param> | |
public MenuRepository(ISqlSugarClient context, ILogger<MenuRepository> logger) : base(context, logger) | |
{ | |
base.Context = context; | |
} | |
/// <summary> | |
/// 扩展方法(私有方法) | |
/// </summary> | |
/// <returns></returns> | |
public string Test() | |
{ | |
return "Test"; | |
} | |
} | |
} |
# 在业务实现类中使用构造函数注入
/// <summary> | |
/// 业务实现类 | |
/// </summary> | |
public class HomeDataService: IHomeDataService | |
{ | |
private readonly IMenuRepository _menuRepository; | |
public HomeDataService(IMenuRepository menuRepository) | |
{ | |
_menuRepository = menuRepository; | |
} | |
public string Get() | |
{ | |
// 可通过仓储调用 SqlSugarClient | |
List<MenuInfo> asSugarClient = _menuRepository.AsSugarClient().Queryable<MenuInfo>().ToList(); | |
// 调用仓储内扩展方法 | |
string test = _menuRepository.Test(); | |
// 调用父仓储公共扩展方法 | |
var list = _menuRepository.ToPageList(1,2); | |
// 返回 "Test" | |
return test; | |
} | |
} | |
/// <summary> | |
/// 业务接口 | |
/// </summary> | |
public interface IHomeDataService: ISingleton | |
{ | |
string Get(); | |
} |