AddAsyncRule() private method

private AddAsyncRule ( [ property1Name, [ property2Name, [ validateAction ) : IAsyncValidationRule
property1Name [
property2Name [
validateAction [
return IAsyncValidationRule
        public static IAsyncValidationRule AddChildValidatable([NotNull] this ValidationHelper validator,
                                                               [NotNull] Expression <Func <IValidatable> > childValidatableGetter)
        {
            Guard.NotNull(validator, nameof(validator));
            Guard.NotNull(childValidatableGetter, nameof(childValidatableGetter));

            Func <IValidatable> getter = childValidatableGetter.Compile();

            return(validator.AddAsyncRule(PropertyName.For(childValidatableGetter), () =>
            {
                IValidatable validatable = getter();

                if (validatable != null)
                {
                    return validatable.Validate().ContinueWith(r =>
                    {
                        ValidationResult result = r.Result;

                        var ruleResult = new RuleResult();

                        foreach (ValidationError error in result.ErrorList)
                        {
                            ruleResult.AddError(error.ErrorText);
                        }

                        return ruleResult;
                    });
                }

                return TaskEx.FromResult(RuleResult.Valid());
            }));
        }
        public static IAsyncValidationRule AddChildValidatable([NotNull] this ValidationHelper validator,
                                                               [NotNull] Expression <Func <IValidatable> > childValidatableGetter)
        {
            Contract.Requires(validator != null);
            Contract.Requires(childValidatableGetter != null);
            Contract.Ensures(Contract.Result <IAsyncValidationRule>() != null);

            Func <IValidatable> getter = childValidatableGetter.Compile();

            return(validator.AddAsyncRule(PropertyName.For(childValidatableGetter), () =>
            {
                IValidatable validatable = getter();

                if (validatable != null)
                {
#if SILVERLIGHT_4
                    validatable.Validate(result =>
                    {
#else
                    return validatable.Validate().ContinueWith(r =>
                    {
                        ValidationResult result = r.Result;
#endif
                        var ruleResult = new RuleResult();

                        foreach (ValidationError error in result.ErrorList)
                        {
                            ruleResult.AddError(error.ErrorText);
                        }

                        return ruleResult;
                    });
                }

                return Task.Factory.StartNew(() => RuleResult.Valid());
            }));
        }
        public static IAsyncValidationRule AddChildValidatableCollection([NotNull] this ValidationHelper validator,
                                                                         [NotNull] Expression <Func <IEnumerable <IValidatable> > > validatableCollectionGetter)
        {
            Contract.Requires(validator != null);
            Contract.Requires(validatableCollectionGetter != null);
            Contract.Ensures(Contract.Result <IAsyncValidationRule>() != null);

            Func <IEnumerable <IValidatable> > getter = validatableCollectionGetter.Compile();

            return(validator.AddAsyncRule(PropertyName.For(validatableCollectionGetter), () =>
            {
                IEnumerable <IValidatable> items = getter();

                if (items == null)
                {
                    return Task.Factory.StartNew(() => RuleResult.Valid());
                }

                return Task.Factory.StartNew(() =>
                {
                    var result = new RuleResult();

                    // Execute validation on all items at the same time, wait for all
                    // to fininish and combine the results.

                    var results = new List <ValidationResult>();

                    var syncEvent = new ManualResetEvent(false);

                    var itemsArray = items as IValidatable[] ?? items.ToArray();
                    int[] numerOfThreadsNotYetCompleted = { itemsArray.Length };

                    foreach (var item in itemsArray)
                    {
#if SILVERLIGHT_4
                        item.Validate(r =>
                        {
                            Exception ex = null;
#else
                        item.Validate().ContinueWith(tr =>
                        {
                            ValidationResult r = tr.Result;
                            AggregateException ex = tr.Exception;
#endif
                            lock (results)
                            {
                                // ReSharper disable ConditionIsAlwaysTrueOrFalse
                                if (ex == null && r != null)
                                // ReSharper restore ConditionIsAlwaysTrueOrFalse
                                {
                                    results.Add(r);
                                }

                                if (Interlocked.Decrement(ref numerOfThreadsNotYetCompleted[0]) == 0)
                                {
                                    syncEvent.Set();
                                }
                            }
                        });
                    }

                    if (numerOfThreadsNotYetCompleted[0] > 0)
                    {
                        // Wait for all items to finish validation
                        syncEvent.WaitOne();

                                          // Add errors from all validation results
                                          foreach (ValidationResult itemResult in results)
                        {
                            foreach (ValidationError error in itemResult.ErrorList)
                            {
                                result.AddError(error.ErrorText);
                            }
                        }
                    }

                    return result;
                });
            }));
        }
        public static IAsyncValidationRule AddChildValidatableCollection([NotNull] this ValidationHelper validator,
                                                                         [NotNull] Expression <Func <IEnumerable <IValidatable> > > validatableCollectionGetter)
        {
            Guard.NotNull(validator, nameof(validator));
            Guard.NotNull(validatableCollectionGetter, nameof(validatableCollectionGetter));

            Func <IEnumerable <IValidatable> > getter = validatableCollectionGetter.Compile();

            return(validator.AddAsyncRule(PropertyName.For(validatableCollectionGetter), () =>
            {
                IEnumerable <IValidatable> items = getter();

                if (items == null)
                {
                    return TaskEx.FromResult(RuleResult.Valid());
                }

                items = items as IValidatable[] ?? items.ToArray();

                if (!items.Any())
                {
                    return TaskEx.FromResult(RuleResult.Valid());
                }

                var result = new RuleResult();

                // Execute validation on all items at the same time, wait for all
                // to finish and combine the results.

                var results = new List <ValidationResult>();

                var tasks = new List <Task <ValidationResult> >();

                foreach (var item in items)
                {
                    var task = item.Validate().ContinueWith(tr =>
                    {
                        ValidationResult r = tr.Result;
                        AggregateException ex = tr.Exception;

                        lock (results)
                        {
                            if (ex == null && r != null)
                            {
                                results.Add(r);
                            }
                        }

                        return tr.Result;
                    });

                    tasks.Add(task);
                }

                var resultTask = TaskEx.WhenAll(tasks).ContinueWith(tr =>
                {
                    if (tr.Exception == null)
                    {
                        // Add errors from all validation results
                        foreach (ValidationResult itemResult in results)
                        {
                            foreach (ValidationError error in itemResult.ErrorList)
                            {
                                result.AddError(error.ErrorText);
                            }
                        }

                        return result;
                    }

                    throw new AggregateException(tr.Exception);
                });

                return resultTask;
            }));
        }