Beispiel #1
0
        public static IEnumerable <ParameterExpression> OfType <T>(Expression expression)
        {
            var finder =
                new TypedParameterExpressionFinder(typeof(T));

            _ = finder.Visit(expression);

            return
                (finder.FoundParameters);
        }
Beispiel #2
0
        private static void ResolveLinks <T>(
            T obj,
            WrapPolicy <T> policy,
            Resource resource,
            IUrlHelper urlHelper)
        {
            if (urlHelper == null)
            {
                return;
            }

            var applicableRules =
                policy
                .LinkingRules
                .Where(r => r.AddPredicate(obj));

            foreach (var rule in applicableRules)
            {
                var methodExpression =
                    rule.MethodCall.Body as MethodCallExpression
                    ?? throw new ApplicationException($"Only MethodCallExpression is supported. Given is: '{rule.MethodCall.Body.GetType()}'");

                var url =
                    Uri.UnescapeDataString(
                        urlHelper.Action(EvaluateActionContext()));

                resource.Link(
                    new NamedLink(
                        rule.Name,
                        new Link(url)));

                UrlActionContext EvaluateActionContext()
                {
                    return
                        (new UrlActionContext()
                    {
                        Protocol =
                            urlHelper
                            .ActionContext
                            .HttpContext
                            .Request
                            .Scheme,

                        Host =
                            urlHelper
                            .ActionContext
                            .HttpContext
                            .Request
                            .Host
                            .Host,

                        Controller =
                            rule.ControllerName,

                        Action =
                            methodExpression.Method.Name,

                        Values =
                            EvaluateValues(),
                    });
                }

                IDictionary <string, object> EvaluateValues()
                {
                    var values =
                        new Dictionary <string, object>();

                    foreach (var argument in GetMethodCallArguments())
                    {
                        var paramT =
                            TypedParameterExpressionFinder
                            .OfType <T>(argument.value)
                            .SingleOrDefault();

                        var value =
                            paramT == null
                                ? Expression
                            .Lambda(argument.value)
                            .Compile()
                            .DynamicInvoke()
                                : Expression
                            .Lambda(argument.value, paramT)
                            .Compile()
                            .DynamicInvoke(obj);

                        values.Add(
                            argument.parameter.Name,
                            value);
                    }

                    foreach (var(name, value) in rule.QueryParameters)
                    {
                        values[name] = value;
                    }

                    foreach (var(name, value) in rule.GetQueryParametersCallback(obj))
                    {
                        values[name] = value;
                    }

                    return
                        (values);
                }

                IEnumerable <(ParameterInfo parameter, Expression value)> GetMethodCallArguments()
                => methodExpression
                .Method
                .GetParameters()
                .Zip(
                    methodExpression.Arguments,
                    (parameter, argument) => (parameter, argument));
            }
        }