ABP拦截器

主要介绍ABP框架中拦截器的实现。在AbpBootstrapper中注册ValidationInterceptorRegistrar验证拦截器注册对象,并初始化。

 /// <summary>
        /// 注册拦截器
        /// </summary>
        private void AddInterceptorRegistrars()
        {
            ValidationInterceptorRegistrar.Initialize(IocManager);
        }

  ValidationInterceptorRegistrar初始化方法包括筛选合适的拦截条件

public static void Initialize(IIocManager iocManager)
        {
            iocManager.IocContainer.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
        }

        private static void Kernel_ComponentRegistered(string key, IHandler handler)
        {
            if (typeof(IApplicationService).GetTypeInfo().IsAssignableFrom(handler.ComponentModel.Implementation))
            {
                handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(ValidationInterceptor)));
            }
        }

如果符合条件,则添加ValidationInterceptor拦截器。

ValidationInterceptor的实现如下:
/// <summary>
    /// 验证拦截器
    /// </summary>
    public class ValidationInterceptor : IInterceptor
    {
        private readonly IIocResolver _iocResolver;
        public ValidationInterceptor(IIocResolver iocResolver)
        {
            this._iocResolver = iocResolver;
        }
        public void Intercept(IInvocation invocation)
        {
            using (var validator = _iocResolver.ResolveAsDisposable<MethodInvocationValidator>())
            {
                validator.Object.Initialize(invocation.MethodInvocationTarget, invocation.Arguments);
                validator.Object.Validate();
            }
            invocation.Proceed();
        }
    }

主要通过MethodInvocationValidator中做些操作:

public class MethodInvocationValidator : ITransientDependency
    {
        #region 声明实例
        private const int MaxRecursiveParameterValidationDepth = 8;
        protected MethodInfo Method { get; private set; }
        protected object[] ParameterValues { get; private set; }
        protected ParameterInfo[] Parameters { get; private set; }
        protected List<ValidationResult> ValidationErrors { get; }
        private readonly IIocResolver _iocResolver;
        private readonly IValidationConfiguration _configuration;
        #endregion

        #region 构造函数
        public MethodInvocationValidator(IValidationConfiguration configuration, IIocResolver iocResolver)
        {
            _configuration = configuration;
            _iocResolver = iocResolver;
            ValidationErrors = new List<ValidationResult>();
        }
        #endregion
        #region 方法
        /// <summary>
        /// 要验证的方法
        /// </summary>
        /// <param name="method">方法</param>
        /// <param name="parameterValues">用于调用的参数列表</param>
        public virtual void Initialize(MethodInfo method, object[] parameterValues)
        {
            Method = method;
            ParameterValues = parameterValues;
            Parameters = method.GetParameters();
        }
        public void Validate()
        {
            CheckInitialized();
            if (Parameters.IsNullOrEmpty())
            {
                return;
            }
            if (!Method.IsPublic)
            {
                return;
            }
            if (IsValidationDisabled())
            {
                return;
            }
            if (Parameters.Length != ParameterValues.Length)
            {
                throw new Exception("Method parameter count does not match with argument count!");
            }
            if (ValidationErrors.Any() && HasSingleNullArgument())
            {
                throw new Exception("Method arguments are not valid! See ValidationErrors for details!");
            }
            for (var i = 0; i < Parameters.Length; i++)
            {
                ValidateMethodParameter(Parameters[i], ParameterValues[i]);

            }
        }

        #endregion
        #region 辅助方法
        protected virtual void CheckInitialized()
        {
            if (Method == null)
            {
                throw new Exception("对象未初始化.请先调用初始化方法.");
            }
        }
        protected virtual bool IsValidationDisabled()
        {
            if (Method.IsDefined(typeof(EnableValidationAttribute), true))
            {
                return false;
            }
            return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableValidationAttribute>(Method) != null;
        }
        protected virtual bool HasSingleNullArgument()
        {
            return Parameters.Length == 1 && ParameterValues[0] == null;
        }
        /// <summary>
        /// 验证给定值的给定参数。
        /// </summary>
        /// <param name="parameterInfo">要验证的方法的参数</param>
        /// <param name="parameterValue">要验证的值</param>
        protected virtual void ValidateMethodParameter(ParameterInfo parameterInfo, object parameterValue)
        {
            if (parameterValue == null)
            {
                if (!parameterInfo.IsOptional &&
                    !parameterInfo.IsOut &&
                    !TypeHelper.IsPrimitiveExtendedIncludingNullable(parameterInfo.ParameterType, includeEnums: true))
                {
                    ValidationErrors.Add(new ValidationResult(parameterInfo.Name + " is null!", new[] { parameterInfo.Name }));
                }

                return;
            }
            ValidateObjectRecursively(parameterValue, 1);
        }

        protected virtual void ValidateObjectRecursively(object validatingObject, int currentDepth)
        {
            if (currentDepth > MaxRecursiveParameterValidationDepth)
            {
                return;
            }
            if (validatingObject == null)
            {
                return;
            }
            SetDataAnnotationAttributeErrors(validatingObject);
            //Validate items of enumerable
            if (validatingObject is IEnumerable && !(validatingObject is IQueryable))
            {
                foreach (var item in (validatingObject as IEnumerable))
                {
                    ValidateObjectRecursively(item, currentDepth + 1);
                }
            }
            if (validatingObject is IEnumerable)
            {
                return;
            }
            var validatingObjectType = validatingObject.GetType();
            //不针对原始对象进行递归验证
            if (TypeHelper.IsPrimitiveExtendedIncludingNullable(validatingObjectType))
            {
                return;
            }
            var properties = TypeDescriptor.GetProperties(validatingObject).Cast<PropertyDescriptor>();
            foreach (var property in properties)
            {
                if (property.Attributes.OfType<DisableValidationAttribute>().Any())
                {
                    continue;
                }

                ValidateObjectRecursively(property.GetValue(validatingObject), currentDepth + 1);
            }
        }
        /// <summary>
        /// 检查DataAnnotations属性的所有属性。
        /// </summary>
        protected virtual void SetDataAnnotationAttributeErrors(object validatingObject)
        {
            var properties = TypeDescriptor.GetProperties(validatingObject).Cast<PropertyDescriptor>();
            foreach (var property in properties)
            {
                var validationAttributes = property.Attributes.OfType<ValidationAttribute>().ToArray();
                if (validationAttributes.IsNullOrEmpty())
                {
                    continue;
                }

                var validationContext = new ValidationContext(validatingObject)
                {
                    DisplayName = property.DisplayName,
                    MemberName = property.Name
                };

                foreach (var attribute in validationAttributes)
                {
                    var result = attribute.GetValidationResult(property.GetValue(validatingObject), validationContext);
                    if (result != null)
                    {
                        ValidationErrors.Add(result);
                    }
                }
            }

            if (validatingObject is IValidatableObject)
            {
                var results = (validatingObject as IValidatableObject).Validate(new ValidationContext(validatingObject));
                ValidationErrors.AddRange(results);
            }
        }
        #endregion
    }

使用拦截器得先注册,框架中在BasicConventionalRegistrar注册拦截器

public class BasicConventionalRegistrar : IConventionalDependencyRegistrar
    {
        public void RegisterAssembly(IConventionalRegistrationContext context)
        {
            //Windsor Interceptors
            context.IocManager.IocContainer.Register(
              Classes.FromAssembly(context.Assembly)
                  .IncludeNonPublicTypes()
                  .BasedOn<IInterceptor>()
                  .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                  .WithService.Self()
                  .LifestyleTransient()
              );
            //注册拦截器  
            //context.IocManager.IocContainer.Register(
            //    Classes.FromThisAssembly()
            //    .BasedOn<IInterceptor>()
            //    .WithService.Self()
            //    .LifestyleTransient());

            //Transient
            context.IocManager.IocContainer.Register(
                Classes.FromAssembly(context.Assembly)
                    .IncludeNonPublicTypes()
                    .BasedOn<ITransientDependency>()
                    .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                    .WithService.Self()
                    .WithService.DefaultInterfaces()
                    .LifestyleTransient()
                );


        }
    }

在各个模块启动是调用即可

posted @ 2018-04-09 16:43  波峰浪尖  阅读(689)  评论(0编辑  收藏  举报