zoukankan      html  css  js  c++  java
  • 属性声明的方式处理事务的解决方案

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

    }

  • 相关阅读:
    单元测试之道读书笔记(七)
    单元测试之道读书笔记(六)
    单元测试之道读书笔记(五)
    单元测试之道读书笔记(三)
    技术网站推荐
    CentOS7部署Haproxy 1.7.2
    Centos7.0配置MySQL主从服务器
    Centos7.0安装mysql5.6
    centos7配置Java环境
    Centos6.5 DNS配置
  • 原文地址:https://www.cnblogs.com/liuhaili/p/2018700.html
Copyright © 2011-2022 走看看