一、前言

最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net、Unity、PostSharp、Castle Windsor这些方式实现AOP的。但是这不是我想要的,因此一番查找后,使用Autofac、DynamicProxy该方式实现AOP。

二、使用AOP的优势

博主觉得它的优势主要表现在:

  • 将通用功能从业务逻辑中抽离出来,就可以省略大量重复代码,有利于代码的操作和维护。
  • 在软件设计时,抽出通用功能(切面),有利于软件设计的模块化,降低软件架构的复杂程度。也就是说通用的功能就是一个单独的模块,在项目的主业务里面是看不到这些通用功能的设计代码的。

三、引用库

  • Autofac:4.6
  • Autofac.Extras.DynamicProxy:4.1.0
  • Castle.Core:3.2.2

四、实现思路

4.1 定义属性

定义属性,通过当前方法是否包含该属性进行判断开启事务,如果存在该属性则开启事务,否则忽略事务。

事务属性可以设置超时时间、事务范围以及事务隔离级别。

代码如下:

/// <summary>
/// 开启事务属性
/// </summary>
[AttributeUsage(AttributeTargets.Method,Inherited = true)]
public class TransactionCallHandlerAttribute:Attribute
{
/// <summary>
/// 超时时间
/// </summary>
public int Timeout { get; set; } /// <summary>
/// 事务范围
/// </summary>
public TransactionScopeOption ScopeOption { get; set; } /// <summary>
/// 事务隔离级别
/// </summary>
public IsolationLevel IsolationLevel { get; set; } public TransactionCallHandlerAttribute()
{
Timeout = 60;
ScopeOption=TransactionScopeOption.Required;
IsolationLevel=IsolationLevel.ReadCommitted;
}
}

4.2 切面实现

获取当前方法是否包含TransactionCallHandlerAttribute该属性,如果有该属性则开启事务。

本人在此处加入开发模式判断,用于没设置MSDTC产生异常的问题,如果不需要可忽略。

另外日志功能自行实现即可。

代码如下:

/// <summary>
/// 事务 拦截器
/// </summary>
public class TransactionInterceptor:IInterceptor
{
//可自行实现日志器,此处可忽略
/// <summary>
/// 日志记录器
/// </summary>
private static readonly ILog Logger = Log.GetLog(typeof(TransactionInterceptor)); // 是否开发模式
private bool isDev = false;
public void Intercept(IInvocation invocation)
{
if (!isDev)
{
MethodInfo methodInfo = invocation.MethodInvocationTarget;
if (methodInfo == null)
{
methodInfo = invocation.Method;
} TransactionCallHandlerAttribute transaction =
methodInfo.GetCustomAttributes<TransactionCallHandlerAttribute>(true).FirstOrDefault();
if (transaction != null)
{
TransactionOptions transactionOptions = new TransactionOptions();
//设置事务隔离级别
transactionOptions.IsolationLevel = transaction.IsolationLevel;
//设置事务超时时间为60秒
transactionOptions.Timeout = new TimeSpan(0, 0, transaction.Timeout);
using (TransactionScope scope = new TransactionScope(transaction.ScopeOption, transactionOptions))
{
try
{
//实现事务性工作
invocation.Proceed();
scope.Complete();
}
catch (Exception ex)
{
// 记录异常
throw ex;
}
}
}
else
{
// 没有事务时直接执行方法
invocation.Proceed();
}
}
else
{
// 开发模式直接跳过拦截
invocation.Proceed();
}
}
}

4.3 切面注入

博主对Autofac进行了封装,可能与你们的配置不一样,但是,Load(ContainerBuilder builder)该方法内容是一致的,因此注入方式一致的。

通过定义IDependency空接口方式,需要注入的类则继承该接口即可。

代码如下:

/// <summary>
/// 应用程序IOC配置
/// </summary>
public class IocConfig : ConfigBase
{
// 重写加载配置
protected override void Load(ContainerBuilder builder)
{
var assembly = this.GetType().GetTypeInfo().Assembly;
builder.RegisterType<TransactionInterceptor>();
builder.RegisterAssemblyTypes(assembly)
.Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.GetTypeInfo().IsAbstract)
.AsImplementedInterfaces()
.InstancePerLifetimeScope()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(TransactionInterceptor));
}
}

五、例子

/// <summary>
/// 添加文章
/// </summary>
/// <param name="name"></param>
[TransactionCallHandler]
public void AddArticle(string name)
{
BasArticle model=new BasArticle();
model.ArticleID = Guid.Empty;//故意重复,判断是否会回滚。
model.Code = TimestampId.GetInstance().GetId();
model.Name = name;
model.Status = 1;
model.Creater = "测试";
model.Editor = "测试";
this._basArticleRepository.Insert(model);
}

[AOP系列]Autofac+Castle实现AOP事务的更多相关文章

  1. [AOP系列]Autofac+Castle实现AOP日志

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要对一些日志进行输出,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实 ...

  2. .Net中的AOP系列之《将AOP作为架构工具》

    返回<.Net中的AOP>系列学习总目录 本篇目录 编译时初始化和验证 编译时初始化 切面验证的正确用法 真实案例:复习线程 架构约束 强制架构 真实案例:NHibernate 多播 类级 ...

  3. Spring AOP 系列总括

    Spring有两大核心,IOC和AOP.IOC在Java Web项目中无时无刻不在使用,然而AOP用的比较少,尤其是对一些初级程序员,在架构师搭好的框架上开发应用代码,AOP几乎是透明的.然而,项目中 ...

  4. ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)

    前言 本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截 觉得有帮助的朋友~可以左上角点个关注,右下角点个推荐 这里就不详细的赘述IOC是什么 以及DI是什么了 ...

  5. Spring系列22:Spring AOP 概念与快速入门篇

    本文内容 Spring AOP含义和目标 AOP相关概念 声明式AOP快速入门 编程式创建代理对象 Spring AOP含义和目标 OOP: Object-oriented Programming 面 ...

  6. Spring框架系列(五)--面向切面AOP

    背景: 当需要为多个不具有继承关系的对象引入一个公共行为,例如日志.权限验证.事务等功能时,如果使用OOP,需要为每个对象引入这些公共 行为.会产生大量重复代码,并且不利用维护.AOP就是为了解决这个 ...

  7. Spring AOP系列(二) — 动态代理引言

    接上一篇Spring AOP系列(一)- 代理模式,本篇来聊聊动态代理. 动态代理与静态代理的区别 要想了解动态代理与静态代理的区别,需要有两个前置知识点:java程序是如何执行的以及类加载机制. j ...

  8. Spring AOP系列(一)— 代理模式

    Spring AOP系列(一)- 代理模式 AOP(Aspect Oriented Programming)并没有创造或使用新的技术,其底层就是基于代理模式实现.因此我们先来学习一下代理模式. 基本概 ...

  9. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

随机推荐

  1. 多媒体开发库 之 SDL 详解

    SDL 简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的 ...

  2. 深入理解CSS3 Flexbox

    一.前言 Flexbox 是一个 CSS3 的盒子模型 ( box model ),顾名思义它就是一个灵活的盒子 ( Flexible Box ),为什麽最近这个属性才红起来呢?最主要也是因为 CSS ...

  3. sql导出

    第一步: 要求:把Library里面的Readers表导出到MyDB中(注意:读者编号.设置了主键)

  4. 《物联网框架ServerSuperIO教程》-20.网络通讯控制器分组,提高交互的负载平衡能力。v3.6.6 版本发布

    20.1     概述 ServerSuperIO原来在网络通讯模式下,只有一个网络控制器,在自控模式.并发模式和单例模式下时都是异步处理返回的数据,并不会出现性能问题.但是在轮询模式下,一个网络控制 ...

  5. 浏览器本地储存方式有哪些?cookie、localStorage、sessionStorage

    现阶段,浏览器提供的储存方式常用的有三种,cookie.localStorage.sessionStorage 1.cookie 概念:cookie 是浏览器中用于保存少量信息的一个对象 基本特征: ...

  6. Expression 转化为sql(三) --自定义函数

    SQL 语句有很多函数如len(),now()等等.如何来生成这些函数.最近研究也写办法共大家参考. 一.首先建立一个建一个扩展类,控制只能允许这些函数出现,如果出现其他函数就直接报异常. publi ...

  7. Spring 4学习——问题与注意事项(一)

    1.Spring项目依赖的jar包有5个: 2.applicationContext.xml文件中,如下bean的property的name值对应的是HelloWorld类中的setter方法,即na ...

  8. 用JMX远程监控Tomcat

    要通过JMX远程监控Tomcat,首先需要进行Tomcat的JMX远程配置. 注意:此配置添加在catalina.bat文件开头的注释行(rem)后面即可. 不需鉴权的配置: 先修改Tomcat的启动 ...

  9. JS/jQ常用宽高及应用

    关于js的宽高,随便一搜就是一大堆.这个一大堆对我来说可不是什么好事,看的头都大了.所以今天就总结了一些比较会常用的,并说明一下应用场景. 先来扯一下documentElement和body的微妙关系 ...

  10. 常用DOM API

    Node Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法.常见的Node有 element,text,attribute,comment,documen ...