-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a way to do dynamic validation with fluentvalidations
- Loading branch information
Showing
7 changed files
with
75 additions
and
6 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
CleanAspCore/Extensions/FluentValidation/FluentValidationExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System.Linq.Expressions; | ||
using System.Reflection; | ||
|
||
namespace CleanAspCore.Extensions.FluentValidation; | ||
|
||
public static class FluentValidationExtensions | ||
{ | ||
public static void ValidateNullableReferences<TModel>(this AbstractValidator<TModel> validator) | ||
{ | ||
IEnumerable<PropertyInfo> properties = GetNonNullableProperties<TModel>(new NullabilityInfoContext()); | ||
|
||
validator.ApplyRuleToProperties(new GenericNotNullOrEmptyRule(), properties); | ||
} | ||
|
||
private static IEnumerable<PropertyInfo> GetNonNullableProperties<TModel>(NullabilityInfoContext nullabilityInfoContext) => | ||
typeof(TModel) | ||
.GetProperties() | ||
.Where(x => nullabilityInfoContext.Create(x).WriteState == NullabilityState.NotNull); | ||
|
||
private static void ApplyRuleInternal<TModel, TProperty>(AbstractValidator<TModel> validator, IGenericRule rule, PropertyInfo propertyInfo) | ||
{ | ||
var builder = CreateRuleBuilder<TModel, TProperty>(validator, propertyInfo); | ||
rule.ApplyRule(builder); | ||
} | ||
|
||
private static IRuleBuilderInitial<TModel, TProperty> CreateRuleBuilder<TModel, TProperty>(AbstractValidator<TModel> validator, PropertyInfo propertyInfo) | ||
{ | ||
ArgumentNullException.ThrowIfNull(validator); | ||
ArgumentNullException.ThrowIfNull(propertyInfo); | ||
|
||
ParameterExpression entityParam = Expression.Parameter(typeof(TModel), "x"); | ||
Expression columnExpr = Expression.Property(entityParam, propertyInfo); | ||
|
||
return validator.RuleFor(Expression.Lambda<Func<TModel, TProperty>>(columnExpr, entityParam)); | ||
} | ||
|
||
public static void ApplyRuleToProperties<TModel>(this AbstractValidator<TModel> validator, IGenericRule rule, IEnumerable<PropertyInfo> properties) | ||
{ | ||
foreach (PropertyInfo property in properties) | ||
{ | ||
validator.ApplyRuleToProperty(rule, property); | ||
} | ||
} | ||
|
||
public static void ApplyRuleToProperty<TModel>(this AbstractValidator<TModel> validator, IGenericRule rule, PropertyInfo property) | ||
{ | ||
MethodInfo methodInfo = typeof(FluentValidationExtensions).GetMethod(nameof(ApplyRuleInternal), BindingFlags.Static | BindingFlags.NonPublic)!; | ||
Type[] argumentTypes = [typeof(TModel), property.PropertyType]; | ||
MethodInfo genericMethod = methodInfo.MakeGenericMethod(argumentTypes); | ||
genericMethod.Invoke(null, [validator, rule, property]); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
CleanAspCore/Extensions/FluentValidation/GenericNotNullOrEmptyRule.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace CleanAspCore.Extensions.FluentValidation; | ||
|
||
public class GenericNotNullOrEmptyRule : IGenericRule | ||
{ | ||
public void ApplyRule<T, TProperty>(IRuleBuilderInitial<T, TProperty> builder) => builder.NotNull().NotEmpty(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace CleanAspCore.Extensions.FluentValidation; | ||
|
||
public interface IGenericRule | ||
{ | ||
public void ApplyRule<T, TProperty>(IRuleBuilderInitial<T, TProperty> builder); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters