zoukankan      html  css  js  c++  java
  • 搭建Wpf框架(5) —— Wpf使用unity实现AOP

    参考网页: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} 
    ");
                }
                else
                {
                    Debug.WriteLine($"Excuted Successed 
    ");
                }
            }
        }
    
    
        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
    作者:竹天笑
    互相学习,提高自己。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    AJAX
    选择器
    断电原则
    radio为什么不能选择。急急急
    IBase<T>
    委托
    Log4Net
    博弈论 学习笔记
    解决You have new mail in /var/spool/mail/root提示
    Zookeeper分布式安装部署
  • 原文地址:https://www.cnblogs.com/akwkevin/p/14587737.html
Copyright © 2011-2022 走看看