您的位置:首页 > 其它

属性声明的方式处理事务的解决方案

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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: