Skip to content

Commit

Permalink
Additional overload of SetValidator that accepts the propertyvalue.
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremySkinner committed Feb 21, 2020
1 parent be48bb1 commit 3060c48
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 1 deletion.
1 change: 1 addition & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Added Slovenian translations of default error messages.
Added WithMessageArgument to the test helpers.
Transform can now be used to transform property values to other types.
FluentValidationModelValidatorProvider and FluentValidationModelValidator are now public.
Add additional overload of SetValidator that takes a Func that receives the current property value.

8.6.0 - 4 December 2019
Add support for ASP.NET Core 3.1
Expand Down
20 changes: 20 additions & 0 deletions src/FluentValidation.Tests/CollectionValidatorWithParentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,26 @@ public class CollectionValidatorWithParentTests {
results.Errors[0].PropertyName.ShouldEqual("test[0].Surname");
}

[Fact]
public void Creates_validator_using_context_from_property_value() {
var personValidator = new InlineValidator<Person>();

var normalOrderValidator = new InlineValidator<Order>();
normalOrderValidator.RuleFor(x => x.Amount).GreaterThan(0);

var freeOrderValidator = new InlineValidator<Order>();
freeOrderValidator.RuleFor(x => x.Amount).Equal(0);

personValidator.RuleForEach(x => x.Orders)
.SetValidator((p, order) => order.ProductName == "FreeProduct" ? freeOrderValidator : normalOrderValidator);

var result1 = personValidator.Validate(new Person() {Orders = new List<Order> {new Order {ProductName = "FreeProduct"}}});
result1.IsValid.ShouldBeTrue();

var result2 = personValidator.Validate(new Person() {Orders = new List<Order> {new Order()}});
result2.IsValid.ShouldBeFalse();
result2.Errors[0].ErrorCode.ShouldEqual("GreaterThanValidator");
}

public class OrderValidator : AbstractValidator<Order> {
public OrderValidator(Person person) {
Expand Down
2 changes: 2 additions & 0 deletions src/FluentValidation/FluentValidation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Changes in 9.0.0:
* Translations of default error messages into other languages are now lazily-loaded
* Added Slovenian translations of default error messages.
* Added WithMessageArgument to the test helpers.
* Add additional overload of SetValidator that takes a Func that receives the current property value.
* ASP.NET Core: FluentValidationModelValidatorProvider and FluentValidationModelValidator are now public.

Full release notes can be found at https://github.com/FluentValidation/FluentValidation/blob/master/Changelog.txt
</PackageReleaseNotes>
Expand Down
15 changes: 14 additions & 1 deletion src/FluentValidation/Internal/RuleBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class RuleBuilder<T, TProperty> : IRuleBuilderOptions<T, TProperty>, IRul
/// Sets the validator associated with the rule. Use with complex properties where an IValidator instance is already declared for the property type.
/// </summary>
/// <param name="validatorProvider">The validator provider to set</param>
/// <param name="ruleSet"></param>
/// <param name="ruleSets"></param>
public IRuleBuilderOptions<T, TProperty> SetValidator<TValidator>(Func<T, TValidator> validatorProvider, params string[] ruleSets)
where TValidator : IValidator<TProperty> {
validatorProvider.Guard("Cannot pass a null validatorProvider to SetValidator", nameof(validatorProvider));
Expand All @@ -84,6 +84,19 @@ public class RuleBuilder<T, TProperty> : IRuleBuilderOptions<T, TProperty>, IRul
return this;
}

/// <summary>
/// Associates a validator provider with the current property rule.
/// </summary>
/// <param name="validatorProvider">The validator provider to use</param>
/// <param name="ruleSets"></param>
public IRuleBuilderOptions<T, TProperty> SetValidator<TValidator>(Func<T, TProperty, TValidator> validatorProvider, params string[] ruleSets) where TValidator : IValidator<TProperty> {
validatorProvider.Guard("Cannot pass a null validatorProvider to SetValidator", nameof(validatorProvider));
SetValidator(new ChildValidatorAdaptor(context => validatorProvider((T) context.InstanceToValidate, (TProperty) context.PropertyValue), typeof (TValidator)) {
RuleSets = ruleSets
});
return this;
}

/// <summary>
/// Sets the validator associated with the rule. Use with complex properties where an IValidator instance is already declared for the property type.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/FluentValidation/Syntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ public interface IRuleBuilder<T, out TProperty> {
/// <param name="ruleSets"></param>
IRuleBuilderOptions<T, TProperty> SetValidator<TValidator>(Func<T, TValidator> validatorProvider, params string[] ruleSets)
where TValidator : IValidator<TProperty>;

/// <summary>
/// Associates a validator provider with the current property rule.
/// </summary>
/// <param name="validatorProvider">The validator provider to use</param>
/// <param name="ruleSets"></param>
IRuleBuilderOptions<T, TProperty> SetValidator<TValidator>(Func<T, TProperty, TValidator> validatorProvider, params string[] ruleSets)
where TValidator : IValidator<TProperty>;
}


Expand Down

0 comments on commit 3060c48

Please sign in to comment.