Example #1
0
        public CollectionWrapPolicy(
            WrapPolicy <TCollection> collectionPolicy,
            WrapPolicy <TContent> contentPolicy)
        {
            CollectionPolicy =
                collectionPolicy
                ?? throw new ArgumentNullException(nameof(collectionPolicy));

            ContentPolicy =
                contentPolicy
                ?? throw new ArgumentNullException(nameof(contentPolicy));
        }
Example #2
0
        private static void ResolveProperties <T>(
            T obj,
            WrapPolicy <T> policy,
            Resource resource)
        {
            foreach (var rule in policy)
            {
                var name =
                    ResolvePropertyName(
                        rule,
                        policy.UseCamelCase);

                var getterFunc =
                    rule.Getter.Compile();

                resource[name] =
                    getterFunc(obj);
            }
        }
Example #3
0
        /// <summary>
        /// Creates collection of <see cref="Resource"/> from collection of objects of type <typeparamref name="T"/> using supplied policy.
        /// </summary>
        public static IEnumerable <Resource> WrapUsing <T>(
            this IEnumerable <T> collection,
            WrapPolicy <T> policy,
            IUrlHelper urlHelper)
        {
            var getters =
                policy
                .WrappingRules
                .ToDictionary(
                    r => ResolvePropertyName(r, policy.UseCamelCase),
                    r => r.Getter.Compile());

            return
                (collection
                 .Select(item =>
            {
                var resource =
                    CreateResource(item);

                ResolveLinks(
                    item,
                    policy,
                    resource,
                    urlHelper);

                return
                resource;
            }));

            Resource CreateResource(T item)
            {
                var resource = new Resource();

                foreach (var kvp in getters)
                {
                    resource[kvp.Key] = kvp.Value(item);
                }

                return(resource);
            }
        }
Example #4
0
        /// <summary>
        /// Creates <see cref="Resource"/> from object of type <typeparamref name="T"/> using supplied policy.
        /// </summary>
        public static Resource WrapUsing <T>(
            this T obj,
            WrapPolicy <T> policy,
            IUrlHelper urlHelper)
        {
            var resource =
                new Resource();

            ResolveLinks(
                obj,
                policy,
                resource,
                urlHelper);

            ResolveProperties(
                obj,
                policy,
                resource);

            return
                (resource);
        }
Example #5
0
 /// <summary>
 /// Creates collection of <see cref="Resource"/> from collection of objects of type <typeparamref name="T"/> using supplied policy.
 /// </summary>
 public static IEnumerable <Resource> WrapUsing <T>(
     this IEnumerable <T> collection,
     WrapPolicy <T> policy)
 => collection.WrapUsing(
     policy,
     null);
Example #6
0
 /// <summary>
 /// Creates <see cref="Resource"/> from object of type <typeparamref name="T"/> using supplied policy, ignoring any linking rules.
 /// </summary>
 public static Resource WrapUsing <T>(
     this T obj,
     WrapPolicy <T> policy)
 => obj.WrapUsing(
     policy,
     null);
Example #7
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));
            }
        }