/// <summary> /// Initializes a new instance of the <see cref="T:System.Object" /> class. /// </summary> public PredicateRouteSubset(Route route, Type type, PredicateRouteOptions options, MemberExpression accessor, IPredicateRoutesProvider routes) : base(route, type, options, accessor) { Routes = routes; }
private static LambdaExpression Build(IPredicateSchemeProvider scheme, Type paramType, IPredicateRoutesProvider schemeRoutes, IExpression source) { if (paramType == null) { throw new ArgumentNullException(nameof(paramType)); } var factorized = FactorizeExpression(source); var p = Expression.Parameter(paramType); Expression body = null; foreach (var logicalExpression in factorized.Expressions.OfType <ILogicalExpression>()) //Or { Expression intermediateResult = null; foreach (var expression in logicalExpression.Expressions.OfType <RouteExpression>()) //And { var routeSubsetExpression = expression as RouteSubsetExpression; if (routeSubsetExpression != null) { var route = schemeRoutes.GetSubsetRoute(expression.Route); if (route == null) { throw new ArgumentException($"Cannot process '{routeSubsetExpression.Route}' subset route"); } var subsetOperator = GeSubsetOperator(scheme, route, routeSubsetExpression.Query); if (subsetOperator == null) { var message = $"'{expression.Route}' subset route does not support '{routeSubsetExpression.Query}' operator"; throw new ArgumentException(message); } var subExpression = Build(scheme, route.Type, route.Routes, routeSubsetExpression.Subset); var accessor = ParameterReplacer.Replace(p, route.Accessor); var compiledExpression = subsetOperator.Expression(accessor, subExpression); var operatorExpression = expression.Operator; var sourceType = compiledExpression.Type; if (operatorExpression != null) { var @operator = GetOperator(scheme, sourceType, route.Options, operatorExpression.Name); if (@operator == null) { var message = $"'{expression.Route}' route does not support '{operatorExpression.Name}' operator"; throw new ArgumentException(message); } var stringValue = operatorExpression.Value.Trim('\"').Trim('\''); var value = scheme.Converters.Convert(stringValue, sourceType); compiledExpression = @operator.Expression(compiledExpression, sourceType, value); if (operatorExpression.Inverted) { compiledExpression = Expression.Not(compiledExpression); } } intermediateResult = intermediateResult == null ? compiledExpression : Expression.AndAlso(intermediateResult, compiledExpression); } else { var route = schemeRoutes.GetRoute(expression.Route); if (route == null) { var message = $"Unknown '{expression.Route}' route in current context"; throw new ArgumentException(message); } var @operator = GetOperator(scheme, route.Type, route.Options, expression.Operator.Name); if (@operator == null) { var message = $"'{expression.Route}' route does not support '{expression.Operator.Name}' operator"; throw new ArgumentException(message); } var accessor = ParameterReplacer.Replace(p, route.Accessor); var stringValue = expression.Operator.Value.Trim('\"').Trim('\''); var value = scheme.Converters.Convert(stringValue, route.Type); Expression compiledExpression = @operator.Expression(accessor, route.Type, value); if (expression.Operator.Inverted) { compiledExpression = Expression.Not(compiledExpression); } intermediateResult = intermediateResult == null ? compiledExpression : Expression.AndAlso(intermediateResult, compiledExpression); } } if (intermediateResult != null) { body = body == null ? intermediateResult : Expression.OrElse(body, intermediateResult); } } body = body ?? Expression.Constant(true); var lambda = Expression.Lambda(body, p); return(lambda); }