/// <summary>
        /// Attempts to call a method on the dynamic object
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="args"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var runtimeCache = ApplicationContext.Current != null ? ApplicationContext.Current.ApplicationCache.RuntimeCache : new NullCacheProvider();

            var attempt = DynamicInstanceHelper.TryInvokeMember(runtimeCache, this, binder, args, new[]
            {
                typeof(DynamicPublishedContent)
            });

            if (attempt.Success)
            {
                result = attempt.Result.ObjectResult;

                //need to check the return type and possibly cast if result is from an extension method found
                if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
                {
                    //we don't need to cast if it is already DynamicPublishedContent
                    if (attempt.Result.ObjectResult != null && (!(attempt.Result.ObjectResult is DynamicPublishedContent)))
                    {
                        if (attempt.Result.ObjectResult is IPublishedContent)
                        {
                            result = new DynamicPublishedContent((IPublishedContent)attempt.Result.ObjectResult);
                        }
                        else if (attempt.Result.ObjectResult is IEnumerable <DynamicPublishedContent> )
                        {
                            result = new DynamicPublishedContentList((IEnumerable <DynamicPublishedContent>)attempt.Result.ObjectResult);
                        }
                        else if (attempt.Result.ObjectResult is IEnumerable <IPublishedContent> )
                        {
                            result = new DynamicPublishedContentList((IEnumerable <IPublishedContent>)attempt.Result.ObjectResult);
                        }
                    }
                }
                return(true);
            }

            //this is the result of an extension method execution gone wrong so we return dynamic null
            if (attempt.Result != null &&
                attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod &&
                attempt.Exception is TargetInvocationException)
            {
                result = DynamicNull.Null;
                return(true);
            }

            result = null;
            return(false);
        }
Esempio n. 2
0
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            //TODO: Nowhere here are we checking if args is the correct length!

            //NOTE: For many of these we could actually leave them out since we are executing custom extension methods and because
            // we implement IEnumerable<T> they will execute just fine, however, to do that will be quite a bit slower than checking here.

            var firstArg = args.FirstOrDefault();

            //this is to check for 'DocumentTypeAlias' vs 'NodeTypeAlias' for compatibility
            if (firstArg != null && firstArg.ToString().InvariantStartsWith("NodeTypeAlias"))
            {
                firstArg = "DocumentTypeAlias" + firstArg.ToString().Substring("NodeTypeAlias".Length);
            }

            var name = binder.Name;

            if (name == "Single")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] {} : args.Skip(1).ToArray();
                var    single    = Single <DynamicPublishedContent>(predicate, values);
                result = new DynamicPublishedContent(single);
                return(true);
            }
            if (name == "SingleOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    single    = SingleOrDefault <DynamicPublishedContent>(predicate, values);
                if (single == null)
                {
                    result = DynamicNull.Null;
                }
                else
                {
                    result = new DynamicPublishedContent(single);
                }
                return(true);
            }
            if (name == "First")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    first     = First <DynamicPublishedContent>(predicate, values);
                result = new DynamicPublishedContent(first);
                return(true);
            }
            if (name == "FirstOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    first     = FirstOrDefault <DynamicPublishedContent>(predicate, values);
                if (first == null)
                {
                    result = DynamicNull.Null;
                }
                else
                {
                    result = new DynamicPublishedContent(first);
                }
                return(true);
            }
            if (name == "Last")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    last      = Last <DynamicPublishedContent>(predicate, values);
                result = new DynamicPublishedContent(last);
                return(true);
            }
            if (name == "LastOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    last      = LastOrDefault <DynamicPublishedContent>(predicate, values);
                if (last == null)
                {
                    result = DynamicNull.Null;
                }
                else
                {
                    result = new DynamicPublishedContent(last);
                }
                return(true);
            }
            if (name == "Where")
            {
                string predicate = firstArg.ToString();
                var    values    = args.Skip(1).ToArray();
                //TODO: We are pre-resolving the where into a ToList() here which will have performance impacts if there where clauses
                // are nested! We should somehow support an QueryableDocumentList!
                result = new DynamicPublishedContentList(Where <DynamicPublishedContent>(predicate, values).ToList());
                return(true);
            }
            if (name == "OrderBy")
            {
                //TODO: We are pre-resolving the where into a ToList() here which will have performance impacts if there where clauses
                // are nested! We should somehow support an QueryableDocumentList!
                result = new DynamicPublishedContentList(OrderBy <DynamicPublishedContent>(firstArg.ToString()).ToList());
                return(true);
            }
            if (name == "Take")
            {
                result = new DynamicPublishedContentList(this.Take <DynamicPublishedContent>((int)firstArg));
                return(true);
            }
            if (name == "Skip")
            {
                result = new DynamicPublishedContentList(this.Skip <DynamicPublishedContent>((int)firstArg));
                return(true);
            }
            if (name == "InGroupsOf")
            {
                int groupSize;
                if (int.TryParse(firstArg.ToString(), out groupSize))
                {
                    result = InGroupsOf(groupSize);
                    return(true);
                }
                result = DynamicNull.Null;
                return(true);
            }
            if (name == "GroupedInto")
            {
                int groupCount;
                if (int.TryParse(firstArg.ToString(), out groupCount))
                {
                    result = GroupedInto(groupCount);
                    return(true);
                }
                result = DynamicNull.Null;
                return(true);
            }
            if (name == "GroupBy")
            {
                result = GroupBy(firstArg.ToString());
                return(true);
            }
            if (name == "Average" || name == "Min" || name == "Max" || name == "Sum")
            {
                result = Aggregate(args, name);
                return(true);
            }
            if (name == "Union")
            {
                // check DynamicPublishedContentList before IEnumerable<...> because DynamicPublishedContentList
                // is IEnumerable<...> so ... the check on DynamicPublishedContentList would never be reached.

                var firstArgAsDynamicPublishedContentList = firstArg as DynamicPublishedContentList;
                if (firstArgAsDynamicPublishedContentList != null)
                {
                    result = new DynamicPublishedContentList(Items.Union((firstArgAsDynamicPublishedContentList).Items));
                    return(true);
                }

                var firstArgAsIEnumerable = firstArg as IEnumerable <DynamicPublishedContent>;
                if (firstArgAsIEnumerable != null)
                {
                    result = new DynamicPublishedContentList(Items.Union(firstArgAsIEnumerable));
                    return(true);
                }
            }
            if (name == "Except")
            {
                if ((firstArg as IEnumerable <DynamicPublishedContent>) != null)
                {
                    result = new DynamicPublishedContentList(Items.Except(firstArg as IEnumerable <DynamicPublishedContent>, new DynamicPublishedContentIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Intersect")
            {
                if ((firstArg as IEnumerable <DynamicPublishedContent>) != null)
                {
                    result = new DynamicPublishedContentList(Items.Intersect(firstArg as IEnumerable <DynamicPublishedContent>, new DynamicPublishedContentIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Distinct")
            {
                result = new DynamicPublishedContentList(Items.Distinct(new DynamicPublishedContentIdEqualityComparer()));
                return(true);
            }
            if (name == "Pluck" || name == "Select")
            {
                result = Pluck(args);
                return(true);
            }

            //ok, now lets try to match by member, property, extensino method
            var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
            {
                typeof(IEnumerable <DynamicPublishedContent>),
                typeof(DynamicPublishedContentList)
            });

            if (attempt.Success)
            {
                result = attempt.Result.ObjectResult;

                //need to check the return type and possibly cast if result is from an extension method found
                if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
                {
                    //we don't need to cast if the result is already DynamicPublishedContentList
                    if (attempt.Result.ObjectResult != null && (!(attempt.Result.ObjectResult is DynamicPublishedContentList)))
                    {
                        if (attempt.Result.ObjectResult is IPublishedContent)
                        {
                            result = new DynamicPublishedContent((IPublishedContent)attempt.Result.ObjectResult);
                        }
                        else if (attempt.Result.ObjectResult is IEnumerable <DynamicPublishedContent> )
                        {
                            result = new DynamicPublishedContentList((IEnumerable <DynamicPublishedContent>)attempt.Result.ObjectResult);
                        }
                        else if (attempt.Result.ObjectResult is IEnumerable <IPublishedContent> )
                        {
                            result = new DynamicPublishedContentList((IEnumerable <IPublishedContent>)attempt.Result.ObjectResult);
                        }
                    }
                }
                return(true);
            }

            //this is the result of an extension method execution gone wrong so we return dynamic null
            if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod &&
                attempt.Exception != null && attempt.Exception is TargetInvocationException)
            {
                result = DynamicNull.Null;
                return(true);
            }

            result = null;
            return(false);
        }