属性声明的方式处理事务的解决方案
2011-04-17 10:06
232 查看
需求:像wcf一样在方法上面加上属性,那么在此方法里面的执行代码便支持事务
方案
1.方法上需要定义属性
2.判断属性拦截方法
3.如果要拦截方法就需要使用拦截器来调用
上代码:
下面是拦截器代码,使用的是using LinFu.DynamicProxy;动态代理,所以在些方法的时候需要声明virtual
public class Interceptor<T> : IInterceptor
{
private T _target;
private Dictionary<string, Attribute> _methodAttributeCache = new Dictionary<string, Attribute>();
public Interceptor(T target)
{
this._target = target;
foreach (MethodInfo mInfo in typeof(T).GetMethods())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
{
if (attr.GetType() == typeof(OperationBehaviorAttribute))
{
if (!_methodAttributeCache.ContainsValue(attr))
_methodAttributeCache.Add( typeof(T).FullName+"."+ mInfo.Name, attr);
}
}
}
}
public object Intercept(InvocationInfo info)
{
//判断是否有事务属性
var methodFullName = typeof(T).FullName + "." + info.TargetMethod.Name;
if (_methodAttributeCache.ContainsKey(methodFullName))
{
var haverequired = ((OperationBehaviorAttribute)_methodAttributeCache[methodFullName]).TransactionScopeRequired;
if (haverequired)
{
using (TransactionScope tran = new TransactionScope(TransactionScopeOption.Required))
{
var result= info.TargetMethod.Invoke(this._target, info.Arguments);
tran.Complete();
return result;
}
}
else
return info.TargetMethod.Invoke(this._target, info.Arguments);
}
else
return info.TargetMethod.Invoke(this._target, info.Arguments);
}
}
下面是调用类,这个类我使用的是单点基类来完成调用的,当然这个单点基类并非真正意义上的单点调用
/// <summary>
/// 单例基类
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonBase<T> where T : class,new()
{
private static T _Instance = null;
private readonly static object _lock = new object();
/// <summary>
/// 单例
/// </summary>
public static T Instance
{
get
{
if (_Instance == null)
{
lock (_lock)
{
if (_Instance == null)
_Instance = new ProxyFactory().CreateProxy<T>(new Interceptor<T>(new T()));
}
}
return _Instance;
}
}
}
类的定义方式
public class UserDAL : SingletonBase<UserDAL>
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
[OperationBehavior(TransactionScopeRequired=true)]
public virtual string GetName()
{
return "a";
}
}
调用方式
static void Main(string[] args)
{
UserDAL.Instance.GetName();
}
方案
1.方法上需要定义属性
2.判断属性拦截方法
3.如果要拦截方法就需要使用拦截器来调用
上代码:
下面是拦截器代码,使用的是using LinFu.DynamicProxy;动态代理,所以在些方法的时候需要声明virtual
public class Interceptor<T> : IInterceptor
{
private T _target;
private Dictionary<string, Attribute> _methodAttributeCache = new Dictionary<string, Attribute>();
public Interceptor(T target)
{
this._target = target;
foreach (MethodInfo mInfo in typeof(T).GetMethods())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
{
if (attr.GetType() == typeof(OperationBehaviorAttribute))
{
if (!_methodAttributeCache.ContainsValue(attr))
_methodAttributeCache.Add( typeof(T).FullName+"."+ mInfo.Name, attr);
}
}
}
}
public object Intercept(InvocationInfo info)
{
//判断是否有事务属性
var methodFullName = typeof(T).FullName + "." + info.TargetMethod.Name;
if (_methodAttributeCache.ContainsKey(methodFullName))
{
var haverequired = ((OperationBehaviorAttribute)_methodAttributeCache[methodFullName]).TransactionScopeRequired;
if (haverequired)
{
using (TransactionScope tran = new TransactionScope(TransactionScopeOption.Required))
{
var result= info.TargetMethod.Invoke(this._target, info.Arguments);
tran.Complete();
return result;
}
}
else
return info.TargetMethod.Invoke(this._target, info.Arguments);
}
else
return info.TargetMethod.Invoke(this._target, info.Arguments);
}
}
下面是调用类,这个类我使用的是单点基类来完成调用的,当然这个单点基类并非真正意义上的单点调用
/// <summary>
/// 单例基类
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonBase<T> where T : class,new()
{
private static T _Instance = null;
private readonly static object _lock = new object();
/// <summary>
/// 单例
/// </summary>
public static T Instance
{
get
{
if (_Instance == null)
{
lock (_lock)
{
if (_Instance == null)
_Instance = new ProxyFactory().CreateProxy<T>(new Interceptor<T>(new T()));
}
}
return _Instance;
}
}
}
类的定义方式
public class UserDAL : SingletonBase<UserDAL>
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
[OperationBehavior(TransactionScopeRequired=true)]
public virtual string GetName()
{
return "a";
}
}
调用方式
static void Main(string[] args)
{
UserDAL.Instance.GetName();
}
相关文章推荐
- Spring事务处理时自我调用的解决方案及一些实现方式的风险
- 【ASP.NET】DataContract序列化,反序列化对象中包含用接口声明的属性时的处理方法
- ExtJs中grid的dataIndex为传回Json数据的一个对象的一个属性时处理方式
- Spring事务中涉及到多线程的处理方式
- Spring有几种事务处理方式
- 分布式事务的典型处理方式:2PC、TCC、异步确保和最大努力型
- JSP自定义标签_属性接收复杂类型处理方式
- Struts2 OSIV模式下的异常处理及事务回滚解决方案
- Java Bean 中使用JDBC方式进行事务处理
- spring 事务操作 声明方式
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
- viewcontroller的成员变量和属性在viewdidunload中的不同处理方式
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
- 三种事务处理方式比较
- 开源夏令营之foldcolumn工具及解决方案(四)数值精度与对齐方式处理
- Spring学习5-Spring整合JDBC及其事务处理(注解方式)
- Java Bean 中使用JDBC方式进行事务处理
- .NET 跨数据库事务处理二种方式
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别