zoukankan      html  css  js  c++  java
  • 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()
                    );
    
    
            }
        }

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

  • 相关阅读:
    C# WinForm判断Win7下程序是否以管理员身份运行
    C#设置文件(夹)权限
    验证字符串是否为有效的IP地址
    内存对齐
    C#线程启动时传入参数
    写字符串内容到文件
    Thread.Abort() Is Evil.
    如何优雅地控制线程状态
    C#读取文件,返回字符串形式的文件内容
    关于产生不重复随机数的算法 C#
  • 原文地址:https://www.cnblogs.com/SecondSun/p/8761006.html
Copyright © 2011-2022 走看看