protected ValidationContext CreateNewValidationContextForChildValidator(object instanceToValidate, PropertyValidatorContext propertyValidatorContext, IValidatorSelector validatorSelector)
        {
            var propertyChain = new PropertyChain(propertyValidatorContext.PropertyChain);
            propertyChain.Add(propertyValidatorContext.Member);

            return new ValidationContext(instanceToValidate, propertyChain, validatorSelector);
        }
		public void Should_not_be_subchain() {
			chain.Add("Foo");

			var otherChain = new PropertyChain();
			otherChain.Add("Bar");

			otherChain.IsChildChainOf(chain).ShouldBeFalse();
		}
		public void Should_be_subchain() {
			chain.Add("Parent");
			chain.Add("Child");

			var childChain = new PropertyChain(chain);
			childChain.Add("Grandchild");

			childChain.IsChildChainOf(chain).ShouldBeTrue();
		}
        public void Should_not_be_subchain()
        {
            chain.Add("Foo");

            var otherChain = new PropertyChain();

            otherChain.Add("Bar");

            otherChain.IsChildChainOf(chain).ShouldBeFalse();
        }
        public void Should_be_subchain()
        {
            chain.Add("Parent");
            chain.Add("Child");

            var childChain = new PropertyChain(chain);

            childChain.Add("Grandchild");

            childChain.IsChildChainOf(chain).ShouldBeTrue();
        }
        public IEnumerable <ValidationFailure> Validate(PropertyValidatorContext context)
        {
            var instanceToValidate = context.PropertyValue;

            if (instanceToValidate == null)
            {
                return(Enumerable.Empty <ValidationFailure>());
            }

            var propertyChain = new PropertyChain(context.PropertyChain);

            propertyChain.Add(context.PropertyName);

            //Selector should not propogate to complex properties.
            //If this property has been included then all child properties should be included.

            var newContext = new ValidationContext <TProperty>((TProperty)instanceToValidate, propertyChain, new DefaultValidatorSelector());
            var results    = validator.SelectMany(x => x.Validate(newContext));

            return(results);
        }
        public override IEnumerable<ValidationFailure> Validate(PropertyValidatorContext context)
        {
            if (context.Member == null) {
                throw new InvalidOperationException(string.Format("Nested validators can only be used with Member Expressions."));
            }

            var collection = context.PropertyValue as IEnumerable;

            if (collection == null) {
                yield break;
            }

            int count = 0;

            foreach (var element in collection) {

                if(element == null) {
                    // If an element in the validator is null then we want to skip it to prevent NullReferenceExceptions in the child validator.
                    // We still need to update the counter to ensure the indexes are correct.
                    count++;
                    continue;
                }

                var childPropertyChain = new PropertyChain(context.PropertyChain);
                childPropertyChain.Add(context.Member);
                childPropertyChain.AddIndexer(count++);

                //The ValidatorSelector should not be propogated downwards.
                //If this collection property has been selected for validation, then all properties on those items should be validated.
                var newContext = new ValidationContext(element, childPropertyChain, new DefaultValidatorSelector());

                var results = childValidator.Validate(newContext).Errors;

                foreach (var result in results) {
                    yield return result;
                }
            }
        }