.net 8 web api使用SqlSugar搭建仓储模式+Autofac依赖注入

废话少说直接上重点,使用SqlSugar搭建仓储模式,之前自己搭建的一个相对基础同时还算稳定的一个框架;
创建解决方案….创建项目省过…结果如图:

仓储服务和仓储实现,业务服务以及业务实现外加一个webapi;

我们先从SqlSugarCore项目开始:

1.添加SqlSugarCore引用

dotnet add package SqlSugarCore --version 5.1.4.177

这个类库项目用来提供实体依赖【个人拿来存数据库实体用】

接下来上重点了;

搭建仓储与基础服务:

1.在IRepository中添加SqlSugarCore项目引用,再建一个IBaseRepository接口类,代码如下:

using SqlSugar;

namespace LHJ.IRepository;

/// <summary>
/// 基类接口,其他接口继承该接口
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IBaseRepository<TEntity> where TEntity : class
{
    /// <summary>
    /// 根据ID查询
    /// </summary>
    /// <param name="objId"></param>
    /// <returns></returns>
    Task<TEntity> QueryByID(object objId);

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    Task<bool> Add(TEntity model);

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    Task<bool> Update(TEntity model);

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    Task<bool> DeleteByIds(object[] ids);

    /// <summary>
    /// 获取db对象
    /// </summary>
    /// <param name="config"></param>
    /// <returns></returns>
    public SqlSugarClient GetDb(string config = "0");
}

注意:GetDb方法用来向外提供DbBase,参数自己可以根据后面实例化DbContext时传入对应数据库的configId

服务接口有了,接下来就是具体实现:

在Repository项目中添加SqlSugar的Nuget引用后新建一个DbContext类,代码如下:

using SqlSugar;

namespace LHJ.Repository;

public class DbContext<T> where T : class, new()
{
    public DbContext()
    {
        Db = new SqlSugarClient(new ConnectionConfig()
        {
            ConfigId = "0",
            ConnectionString = BaseDBConfig.ConnectionString,
            DbType = DbType.SqlServer,
            InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
            IsAutoCloseConnection = true,//开启自动释放模式
        });
        //调式代码 用来打印SQL 
        Db.Aop.OnLogExecuting = (sql, pars) =>
        {
            Console.WriteLine(sql + "\r\n" +
                Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
            Console.WriteLine();
        };

    }

    public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
    public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }//用来操作当前表的数据

    //public SimpleClient<Users> UserDb { get { return new SimpleClient<Users>(Db); } }
}

DbContext用来初始化数据库连接,然后再建一个仓储实现类BaseRepository.cs,代码如下:


namespace LHJ.Repository;

/// <summary>
/// 基类实现
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class BaseRepository<TEntity> : DbContext<TEntity>, IBaseRepository<TEntity> where TEntity : class, new()
{
    /// <summary>
    /// 写入实体数据
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> Add(TEntity model)
    {
        //这里需要注意的是,如果使用了Task.Run()就会导致 sql语句日志无法记录改成下面的
        //var i = await Task.Run(() => Db.Insertable(model).ExecuteCommand());
        var i = await Db.Insertable(model).ExecuteCommandAsync();
        return i > 0;
    }

    /// <summary>
    /// 根据ID删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task<bool> DeleteByIds(object[] ids)
    {
        var i = await Db.Deleteable<TEntity>().In(ids).ExecuteCommandAsync();
        return i > 0;
    }

    /// <summary>
    /// 根据ID查询一条数据
    /// </summary>
    /// <param name="objId"></param>
    /// <returns></returns>
    public async Task<TEntity> QueryByID(object objId)
    {
        return await Db.Queryable<TEntity>().InSingleAsync(objId);
    }

    /// <summary>
    /// 更新实体数据
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> Update(TEntity model)
    {
        //这种方式会以主键为条件
        var i = await Db.Updateable(model).ExecuteCommandAsync();
        return i > 0;
    }

    public SqlSugarClient GetDb(string configId) => Db;
}

这里我们继承了IBaseRepository类,同时也基础了DbContext类,这样我们就能通过DbContext实现对应基础数据交互操作;

同时再建一个配置类BaseDBConfig.cs,代码如下:

namespace LHJ.Repository;

public class BaseDBConfig
{

    /// <summary>
    /// 数据库连接字符串oracle
    /// </summary>
    public static string? ConnectionString { get; set; }
}

这里是用来存储数据库字符串,我自己处理单库,如果要多库请使用:

public static List<string>? ConnectionString { get; set; }

这里我建议大家可以单据建一个类库用来提供公共配置支持配置信息【个人搭建写完了才发现,就懒得改了】,还有使用静态字段存储链接字符其实是不恰当的,应该在DBContext初始化的时候读一次配置文件,这样发布后更改数据库相对方便;【主要是为了演示如何搭建,就不改了】

仓储有了,我们就可以搭建逻辑业务,在项目IService中新建IBaseService接口类,代码如下:

namespace LHJ.IService;

public interface IBaseService<TEntity> where TEntity : class
{
    /// <summary>
    /// 根据ID列表删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    Task<bool> DeleteByIds(object[] ids);

    /// <summary>
    /// 根据ID查询
    /// </summary>
    /// <param name="objId"></param>
    /// <returns></returns>
    Task<TEntity> QueryByID(object objId);

    /// <summary>
    /// 添加实体
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    Task<bool> Add(TEntity model);

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>

    Task<bool> Update(TEntity model);
}

在Service项目中新建服务基类Service.cs,代码如下:

/// <summary>
/// 服务基类
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : class, new()
{
    private readonly IBaseRepository<TEntity> baseDal;

    //这里使用依赖注入
    public BaseService(IBaseRepository<TEntity> baseRepository)
    {
        baseDal = baseRepository;
    }

    /// <summary>
    /// 写入实体
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> Add(TEntity model)
    {
        return await baseDal.Add(model);
    }

    /// <summary>
    /// 根据ID删除
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>

    public async Task<bool> DeleteByIds(object[] ids)
    {
        return await baseDal.DeleteByIds(ids);
    }

    /// <summary>
    /// 根据ID查询
    /// </summary>
    /// <param name="objId"></param>
    /// <returns></returns>
    public async Task<TEntity> QueryByID(object objId)
    {
        return await baseDal.QueryByID(objId);
    }

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> Update(TEntity model)
    {
        return await baseDal.Update(model);
    }
}

到此后端的架构基本上算是完成了,但是这个时候启动项目是不会实现基础服务,因此我们需要Autofac注入实现我们的服务:

1.添加服务

dotnet add package Autofac.Extensions.DependencyInjection --version 10.0.0

2.还是添加包引用

dotnet add package Autofac.Extras.DynamicProxy --version 7.1.0

3.新建AutofacModuleRegister.cs类,用来配置Autofac,代码如下:

using Autofac;
using Autofac.Extras.DynamicProxy;
using System.Reflection;

namespace LHJ.WebHost;

public class AutofacModuleRegister : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //注册服务
        //builder.RegisterType<TestService>().As<ITestService>();

        //builder.RegisterType<TestRepository>().As<ITestRepository>();

        //注册Service
        var assemblysServices = Assembly.Load("LHJ.Service");
        builder.RegisterAssemblyTypes(assemblysServices)
            .InstancePerDependency()//默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象
           .AsImplementedInterfaces()//是以接口方式进行注入,注入这些类的所有的公共接口作为服务(除了释放资源)
           .EnableInterfaceInterceptors(); //引用Autofac.Extras.DynamicProxy;应用拦截器

        //注册Repository
        var assemblysRepository = Assembly.Load("LHJ.Repository");
        builder.RegisterAssemblyTypes(assemblysRepository)
            .InstancePerDependency()//默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象
           .AsImplementedInterfaces()//是以接口方式进行注入,注入这些类的所有的公共接口作为服务(除了释放资源)
           .EnableInterfaceInterceptors(); //引用Autofac.Extras.DynamicProxy;应用拦截器

    }
}

根据程序集注册,请求一次实例化注入一次服务,请求结束自动释放继承IDisposable的对象资源;

在appsettings.json中配置你自己的连接字符串:

"AppSetting": {
  "ConnectionStringSqlServer": "Data Source=xxxx;Initial Catalog=your_Db;User Id=sa;Password=xxxx;Encrypt=True;TrustServerCertificate=True;",
  "ConnectionStringOracle": "Server=.;Database=BookStore;Trusted_Connection=True;TrustServerCertificate=True"
}

而后在Program.cs中启用以上配置,代码如下:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using LHJ.Repository;
using LHJ.WebHost;

var builder = WebApplication.CreateBuilder(args);

// 使用 Autofac 作为服务容器
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// 配置 Autofac 容器
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    // 注册服务
    containerBuilder.RegisterModule(new AutofacModuleRegister());
});

// Add services to the container.

builder.Services.AddControllers();

BaseDBConfig.ConnectionString = builder.Configuration.GetSection("AppSetting:ConnectionStringSqlServer").Value;

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
//    app.UseSwagger();
//    app.UseSwaggerUI();
//}

app.UseSwagger();
app.UseSwaggerUI();

app.UseAuthorization();

app.MapControllers();

app.Run();

如果需要使用多库,则将数据库配置全部读进BaseDBConfig.ConnectionString;

这个时候你的项目【Webhost】应该可以正常启动,我们在SqlSugarCore项目下新建一个实体类Users.cs,代码如下:

using SqlSugar;

namespace LHJ.SqlSugarCore.Entities;

/// <summary>
/// 
///</summary>
[SugarTable("User")]
public class Users
{
    /// <summary>
    ///  
    ///</summary>
    [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)]
    public int Id  { get; set; }

    /// <summary>
    ///  
    ///</summary>
    [SugarColumn(ColumnName = "Name")]
    public string? Name { get; set; }

    /// <summary>
    ///  
    ///</summary>
    [SugarColumn(ColumnName = "Email")]
    public string? Email { get; set; }
}

IService项目下新建一个类ITestService,代码如下:


using LHJ.SqlSugarCore.Entities;


namespace LHJ.IService.IServices;

public interface ITestService:IBaseService<Users>
{
}

在Service项目中新建TestService类用于实现测试的接口类,代码如下:

using LHJ.IRepository;
using LHJ.IService.IServices;
using LHJ.SqlSugarCore.Entities;

namespace LHJ.Service.Services;

public class TestService : BaseService<Users>, ITestService
{
    IBaseRepository<Users> _baseRepository;
    public TestService(IBaseRepository<Users> baseRepository) : base(baseRepository)
    {
        _baseRepository = baseRepository;
    }


}

在IRepository项目中新建ITestRepository.cs类,代码如下:

using LHJ.SqlSugarCore.Entities;

namespace LHJ.IRepository.ManagerRepository;

public interface ITestPlanRepository : IBaseRepository<Users>
{

}

在Repository中新建TestPlanRepository类基础ITestRepository,代码如下:

using LHJ.IRepository.ManagerRepository;
using LHJ.SqlSugarCore.Entities;

namespace LHJ.Repository.SugarRepository;

public class TestRepository : BaseRepository<Users>, ITestPlanRepository
{

}

最后添加一个控制器TestController.cs,代码如下:


using LHJ.IService.IServices;
using LHJ.SqlSugarCore.Entities;
using Microsoft.AspNetCore.Mvc;

namespace LHJ.WebHost.Controllers;

[ApiController]
[Route("api/[controller]/[action]")]
public class TestController : ControllerBase
{
    private readonly ITestService testService;

    public TestController(ITestService _testService) { this.testService = _testService; }

    [HttpGet]
    public Task<Users> GetUser(int Id)
    {
        return testService.QueryByID(Id);
    }
}

然后启动项目【Webhost】确保你使用的数据库与实体类符合,然后查询

完成!!

来源链接:https://www.cnblogs.com/hadxs/p/18721609

© 版权声明
THE END
支持一下吧
点赞6 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容