首页 > 编程语言 > 详细

搭建Wpf框架(5) —— Wpf使用unity实现AOP

时间:2021-03-28 11:27:43      阅读:20      评论:0      收藏:0      [点我收藏+]

参考网页:Unity使用(二):Unity.Interception实现AOP-坤哥网 (kungge.com)

只要实现了ioc,就可以使用aop。

1.安装Unity.Interception

2.原先的prism注册Type的方法为 

 containerRegistry.Register<IDataProvider, ApiDataProvider>();

 现在修改修改成

  var container = PrismIocExtensions.GetContainer(containerRegistry);

 container.AddNewExtension<Interception>()//add Extension Aop
                    .RegisterSingleton<IDataProvider, ApiDataProvider>(new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>());

3.aop方法的实现

实现一个基类

  public abstract class BaseAOPHandler : ICallHandler
    {
        public int Order { get; set; }

        public virtual void Befor(IMethodInvocation input)
        {
           
        }

        public virtual void After(IMethodInvocation input, IMethodReturn result)
        {
           
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            Befor(input);
            var methodReturn = getNext()(input, getNext);
            After(input, methodReturn);

            return methodReturn;
        }
    }

  具体实现

  public class LogHandler : BaseAOPHandler
    {
        public override void Befor(IMethodInvocation input)
        {
            Debug.WriteLine("-------------Method Excute Befored-------------");
            Debug.WriteLine($"Method Name:{input.MethodBase.Name}");
            if (input.Arguments.Count > 0)
            {
                Debug.WriteLine("Arguments:");
                for (int i = 0; i < input.Arguments.Count; i++)
                {
                    Debug.WriteLine($"parameterName:{input.Arguments.ParameterName(i)},parameterValue:{input.Arguments[i]}");
                }
            }
        }

        public override void After(IMethodInvocation input, IMethodReturn result)
        {
            Debug.WriteLine("-------------Method Excute After-------------");
            if (result.Exception != null)
            {
                Debug.WriteLine($"Exception:{result.Exception.Message} \n");
            }
            else
            {
                Debug.WriteLine($"Excuted Successed \n");
            }
        }
    }


    public class LogHandlerAttribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new LogHandler() { Order = this.Order };
        }
    }
}

  原理很简单,就是方法执行前执行(Befor)可以进行校验,进行打印。方法执行(After)后进行记录等。

4.使用的地方:

 public interface IDataProvider
    {
        Task<WebResponse<string>> GetToken(string url, string userName, string password, int headMode, TimeSpan timeout);

        [LogHandler]
        Task<WebResponse<T>> GetData<T>(string url, Dictionary<string, string> data);

        [LogHandler]
        Task<WebResponse<T>> GetData<T>(string url, string json = "{}");
        Task<UploadResult> UploadFileByForm(string path);
    }

  另外本框架还实现了:

删除日志记录:

技术分享图片
    public class DataDeleteLogHandle : WriteDataLogHandle
    {
        public DataDeleteLogHandle(UserLogType logType, string nameField, string dataName)
            : base(logType, nameField, dataName)
        {
        }


        private string _names;
        public override void Befor(IMethodInvocation input)
        {
            List<string> ids = input.Arguments[0] as List<string>;
            var q = input.Target.GetType().GetMethod("GetIQueryable").Invoke(input.Target, new object[] { false }) as IQueryable;
            var deleteList = q.Where("@0.Contains(Id)", ids).CastToList<object>();

            _names = string.Join(",", deleteList.Select(x => x.GetPropertyValue(_nameField)?.ToString()));
        }

        public override void After(IMethodInvocation input, IMethodReturn result)
        {
            if (result.Exception == null)
            {
                var log = ContainerLocator.Current.Resolve<IBase_UserLogBusiness>();
                log.WriteUserLog(_logType, $"删除{_dataName}:{_names}").Wait();
            }
        }
    }

    public class DataDeleteLogAttribute : HandlerAttribute
    {
        protected UserLogType _logType { get; }
        protected string _dataName { get; }
        protected string _nameField { get; }

        public DataDeleteLogAttribute(UserLogType logType, string nameField, string dataName)
        {
            _logType = logType;
            _dataName = dataName;
            _nameField = nameField;
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new DataDeleteLogHandle(_logType, _nameField, _dataName) { Order = this.Order };
        }
    }
View Code

数据重复检验:

技术分享图片
    public class DataRepeatValidateHandle : BaseAOPHandler
    {
        public DataRepeatValidateHandle(string[] validateFields, string[] validateFieldNames, bool allData = false, bool matchOr = true)
        {
            if (validateFields.Length != validateFieldNames.Length)
                throw new Exception("校验列与列描述信息不对应!");

            _allData = allData;
            _matchOr = matchOr;
            for (int i = 0; i < validateFields.Length; i++)
            {
                _validateFields.Add(validateFields[i], validateFieldNames[i]);
            }
        }

        private bool _allData { get; }
        private bool _matchOr { get; }
        private Dictionary<string, string> _validateFields { get; } = new Dictionary<string, string>();

        public override void Befor(IMethodInvocation input)
        {
            Type entityType = input.Arguments[0].GetType();
            var data = input.Arguments[0];
            List<string> whereList = new List<string>();
            var properties = _validateFields
                .Where(x => !data.GetPropertyValue(x.Key).IsNullOrEmpty())
                .ToList();
            properties.ForEach((aProperty, index) =>
            {
                whereList.Add($" {aProperty.Key} = @{index} ");
            });
            IQueryable q = null;
            if (_allData)
            {
                var repository = input.Target.GetPropertyValue("Service") as IDbAccessor;
                var method = repository.GetType().GetMethod("GetIQueryable");
                q = method.MakeGenericMethod(entityType).Invoke(repository, new object[] { false }) as IQueryable;
            }
            else
                q = input.Target.GetType().GetMethod("GetIQueryable").Invoke(input.Target, new object[] { false }) as IQueryable;
            q = q.Where("Id != @0", data.GetPropertyValue("Id"));
            q = q.Where(
                string.Join(_matchOr ? " || " : " && ", whereList),
                properties.Select(x => data.GetPropertyValue(x.Key)).ToArray());
            var list = q.CastToList<object>();
            if (list.Count > 0)
            {
                var repeatList = properties
                    .Where(x => list.Any(y => !y.GetPropertyValue(x.Key).IsNullOrEmpty()))
                    .Select(x => x.Value)
                    .ToList();

                throw new BusException($"{string.Join(_matchOr ? "" : "", repeatList)}已存在!");
            }
        }
    }

    public class DataRepeatValidateAttribute : HandlerAttribute
    {
        protected string[] _validateFields { get; }
        protected string[] _validateFieldNames { get; }
        protected bool _allData { get; }
        protected bool _matchOr { get; }

        public DataRepeatValidateAttribute(string[] validateFields, string[] validateFieldNames, bool allData = false, bool matchOr = true)
        {
            _validateFields = validateFields;
            _validateFieldNames = validateFieldNames;
            _allData = allData;
            _matchOr = matchOr;
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new DataRepeatValidateHandle(_validateFields, _validateFieldNames, _allData, _matchOr) { Order = this.Order };
        }
    }
View Code

数据保存记录:

技术分享图片
    public class DataSaveLogHandle : WriteDataLogHandle
    {
        public DataSaveLogHandle(UserLogType logType, string nameField, string dataName)
            : base(logType, nameField, dataName)
        {
        }

        bool _isNew;

        public override void Befor(IMethodInvocation input)
        {
            var obj = input.Arguments[0];
            _isNew = string.IsNullOrEmpty(obj.GetPropertyValue("Id")?.ToString());
        }

        public override void After(IMethodInvocation input, IMethodReturn result)
        {
            if (result.Exception == null)
            {
                var log = ContainerLocator.Current.Resolve<IBase_UserLogBusiness>();
                var obj = input.Arguments[0];
                log.WriteUserLog(_logType, $"{(_isNew ? "添加":"修改")}{_dataName}:{obj.GetPropertyValue(_nameField)?.ToString()}").Wait();
            }
        }
    }

    public class DataSaveLogAttribute : HandlerAttribute
    {
        protected UserLogType _logType { get; }
        protected string _dataName { get; }
        protected string _nameField { get; }

        public DataSaveLogAttribute(UserLogType logType, string nameField, string dataName)
        {
            _logType = logType;
            _dataName = dataName;
            _nameField = nameField;
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new DataSaveLogHandle(_logType, _nameField, _dataName) { Order = this.Order };
        }
    }
View Code

加上事务处理:

技术分享图片
    public class TransactionalHandle : BaseAOPHandler
    {
        private readonly IsolationLevel _isolationLevel;
        public TransactionalHandle(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
        {
            _isolationLevel = isolationLevel;
        }

        public override void Befor(IMethodInvocation input)
        {
            var repository = input.Target.GetPropertyValue("Service") as IDbAccessor;
            repository.BeginTransaction(_isolationLevel);
        }

        public override void After(IMethodInvocation input, IMethodReturn result)
        {
            var repository = input.Target.GetPropertyValue("Service") as IDbAccessor;
            if (result.Exception == null)
            {      
                try
                {
                    repository.CommitTransaction();
                }
                catch (Exception ex)
                {
                    repository.RollbackTransaction();
                    throw new Exception("系统异常", ex);
                }
            }
            else
            {
                repository.RollbackTransaction();
            }
            
        }

    }

    public class TransactionalAttribute : HandlerAttribute
    {
        private readonly IsolationLevel _isolationLevel;

        public TransactionalAttribute(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
        {
            _isolationLevel = isolationLevel;
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new TransactionalHandle(_isolationLevel) { Order = this.Order };
        }
    }
View Code

添加日志记录的基类:

技术分享图片
 public class WriteDataLogHandle : BaseAOPHandler
    {
        protected UserLogType _logType { get; }
        protected string _dataName { get; }
        protected string _nameField { get; }

        public WriteDataLogHandle(UserLogType logType, string nameField, string dataName)
        {
            _logType = logType;
            _dataName = dataName;
            _nameField = nameField;
        }
    }
View Code

 

搭建Wpf框架(5) —— Wpf使用unity实现AOP

原文:https://www.cnblogs.com/akwkevin/p/14587737.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!