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

    }

  • 相关阅读:
    OpenCV 限制对比度 图像增强
    2000 * 1000的图像截取大小为20 * 20
    在opencv3中的机器学习算法练习:对OCR进行分类
    OpenCV KNN加载训练好的模型
    OpenCV KNN数字分类
    vim简易配置
    shell简明笔记
    命令行关闭和开启ubuntu图形界面
    忘记Oracle数据库中sys等密码的解决方法
    Oracle常见练习题(2020082201)
  • 原文地址:https://www.cnblogs.com/liuhaili/p/2018700.html
Copyright © 2011-2022 走看看