搭建Wpf框架(5) —— Wpf使用unity实现AOP
AIStudio框架汇总及介绍
参考网页: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 }; } }
数据重复检验:
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 }; } }
数据保存记录:
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 }; } }
加上事务处理:
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 }; } }
添加日志记录的基类:
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; } }