1. 首页>
  2. 技术文章>
  3. .net core,AspectCore使用AOP实现SqlSugar事务

.net core,AspectCore使用AOP实现SqlSugar事务

7/23/18 11:08:34 PM 浏览 3576 评论 0

AspectCore Aop SqlSugar 事务

一直很喜欢在方法头加个标签,实现方法体内自动事务,比如标签TransactionCallHandler,用到的AspectCore和SqlSugar均为开源,百度都可以找到GIT地址,最终达到的使用效果如下:

[TransactionCallHandler]
public void Add(ArticleAct act, string username) {
    var article = new BasArticle()
    {
        CommentTimes = 0,
        Content = act.Content,
        Creater = username,
        CreateTime = DateTime.Now,
        ReadTimes = 0,
        Title = act.Title
    };
    _basArticleRepository.Insert(article);
}

方法上加个TransactionCallHandler头,则方法体内自动启用事务。

TransactionCallHandler代码:

public class TransactionCallHandlerAttribute : AbstractInterceptorAttribute
{

    public async override Task Invoke(AspectContext context, AspectDelegate next)
    {
        var mySqlSugarClient = context.ServiceProvider.GetService<MySqlSugarClient>();

        if (mySqlSugarClient.Ado.Transaction != null)
        {
            await next(context);
            return;
        }

        try
        {
            mySqlSugarClient.Ado.BeginTran();

            await next(context);

            mySqlSugarClient.Ado.CommitTran();
        }
        catch (Exception ex)
        {
            mySqlSugarClient.Ado.RollbackTran();

            throw new Exception($"{ex.Message}{Environment.NewLine}{ex.Source}{Environment.NewLine}{ex.StackTrace}");
        }
            
           
    }
}

MySqlSugarClient是继承自SqlSugar,SqlSugarClient的类,内容:

using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using MyCore.Infrastructure.Dependency;
namespace MyCore.Repositories.Common
{
    public class MySqlSugarClient : SqlSugar.SqlSugarClient
    {
        private static ConnectionConfig config = new ConnectionConfig()
        {
            ConnectionString = "数据库链接字符串",
            DbType = DbType.MySql,
            InitKeyType = InitKeyType.Attribute,
            IsAutoCloseConnection = true
           
        };
        public MySqlSugarClient() : base(config)
        { 
          
        }  
    }
}

而仓储的实现举个文章的例子如下:

BasArticleRepository

using System;
using System.Collections.Generic;
using System.Text;
using MyCore.Domain.Model;
using MyCore.Domain.Repositories;
using MyCore.Infrastructure;
using MyCore.Infrastructure.Dependency;
using MyCore.Repositories.Common;
using SqlSugar;
namespace MyCore.Repositories
{
    public class BasArticleRepository : Repository<BasArticle> ,IBasArticleRepository
    {
        public BasArticleRepository(MySqlSugarClient context) : base(context) { }
    }
}

Repository<T>部分代码如下:

public class Repository<T>: IDependency, IRepository<T> where T : class, new()
{
        private static ILogger Log = Ioc.GetService<ILogger>();
        private MySqlSugarClient _context;
        public Repository(MySqlSugarClient context) 
        {
            this._context = context;
            //输出执行的语句
            this._context.Aop.OnLogExecuting = (sql, pars) =>
            {
                Log.Debug(sql + Environment.NewLine + Json.ToJson(pars) + Environment.NewLine);
                //Log.Debug(pars.)
            };
        }
        public void BeginTran()
        {
            this._context.Ado.BeginTran();
        }
        public void CommitTran()
        {
            this._context.Ado.CommitTran();
        }
        public void RollbackTran()
        {
            this._context.Ado.RollbackTran();
        }
}

在Service服务层,直接使用构造函数注入,比如:

public class ArticleService:ApplicationBase,IArticleService
{
        private readonly IBasArticleRepository _basArticleRepository;
        public ArticleService(IBasArticleRepository basArticleRepository) {
            _basArticleRepository = basArticleRepository;
        }
}

对了,别忘记AOP是需要在startup.cs中ConfigureServices加入代码:

services.AddDynamicProxy(config => {
      config.Interceptors.AddTyped<ErrorLogHandler>(method => method.DeclaringType.Name.EndsWith("Service"));
});
return services.BuildAspectCoreServiceProvider();

ErrorLogHandler是统一的错误日志处理,主要代码:

public class ErrorLogHandler: AbstractInterceptorAttribute
{
        protected static ILogger Log = Ioc.GetService<ILogger>();
        public async override Task Invoke(AspectContext context, AspectDelegate next)
        {            
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                //获取参数
                
                Log.Error("传参:" + Json.ToJson(context.Parameters) + Environment.NewLine + ex + Environment.NewLine);
                throw ex;
            }
        }
}


网友讨论