只要十步,你就可以应用表达式树来优化动态调用(二)( 七 )

CreateValidateStringRequiredExp(){return (name, value) =>string.IsNullOrEmpty(value)? ValidateResult.Error($"missing {name}"): ValidateResult.Ok();}protected override IEnumerable CreateExpressionCore(CreatePropertyValidatorInput input){var propertyInfo = input.PropertyInfo;if (propertyInfo.GetCustomAttribute() != null){yield return CreateValidateExpression(input, CreateValidateStringRequiredExp());}}}public class StringLengthPropertyValidatorFactory : PropertyValidatorFactoryBase{private static Expression CreateValidateStringMinLengthExp(int minLength){return (name, value) =>string.IsNullOrEmpty(value) || value.Length < minLength? ValidateResult.Error($"Length of {name} should be great than {minLength}"): ValidateResult.Ok();}protected override IEnumerable CreateExpressionCore(CreatePropertyValidatorInput input){var propertyInfo = input.PropertyInfo;var minlengthAttribute = propertyInfo.GetCustomAttribute();if (minlengthAttribute != null){yield return CreateValidateExpression(input,CreateValidateStringMinLengthExp(minlengthAttribute.Length));}}}public class CreatePropertyValidatorInput{public Type InputType { get; set; } = null!;public Expression InputExpression { get; set; } = null!;public PropertyInfo PropertyInfo { get; set; } = null!;public ParameterExpression ResultExpression { get; set; } = null!;public LabelTarget ReturnLabel { get; set; } = null!;}public class ValidatorFactory : IValidatorFactory{private readonly IEnumerable _propertyValidatorFactories;public ValidatorFactory(IEnumerable propertyValidatorFactories){_propertyValidatorFactories = propertyValidatorFactories;}private Func CreateValidator(Type type){var finalExpression = CreateCore();return finalExpression.Compile();Expression> CreateCore(){// exp for inputvar inputExp = Expression.Parameter(typeof(object), "input");// exp for outputvar resultExp = Expression.Variable(typeof(ValidateResult), "result");// exp for return statementvar returnLabel = Expression.Label(typeof(ValidateResult));var innerExps = new List {CreateDefaultResult()};var validateExpressions = type.GetProperties().SelectMany(p => _propertyValidatorFactories.SelectMany(f =>f.CreateExpression(new CreatePropertyValidatorInput{InputExpression = inputExp,PropertyInfo = p,ResultExpression = resultExp,ReturnLabel = returnLabel,InputType = type,}))).ToArray();innerExps.AddRange(validateExpressions);innerExps.Add(Expression.Label(returnLabel, resultExp));// build whole blockvar body = Expression.Block(new[] {resultExp},innerExps);// build lambda from bodyvar final = Expression.Lambda>(body,inputExp);return final;Expression CreateDefaultResult(){var okMethod = typeof(ValidateResult).GetMethod(nameof(ValidateResult.Ok));Debug.Assert(okMethod != null, nameof(okMethod) + " != null");var methodCallExpression = Expression.Call(okMethod);var re = Expression.Assign(resultExp, methodCallExpression);/*** final as:* result = ValidateResult.Ok()*/return re;}}}private static readonly ConcurrentDictionary> ValidateFunc =new ConcurrentDictionary>();public Func


推荐阅读