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

需求:像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();

}

原文地址:https://www.cnblogs.com/liuhaili/p/2018700.html