First I have registered my custom attribute :
container.Register<ValidationAttribute, CustomValidationAttribute>();
I have created a custom DataAnnotationsModelValidatorProvider :
public class CustomModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
private ValidationAttribute _customValidationAttribute;
public CustomModelValidatorProvider(
ValidationAttribute customValidationAttribute) : base()
{
_customValidationAttribute = customValidationAttribute;
}
protected override IEnumerable<ModelValidator> GetValidators(
ModelMetadata metadata, ControllerContext context,
IEnumerable<Attribute> attributes)
{
IList<Attribute> customAttributes = attributes.ToList();
// It will be added for each property of the model
customAttributes.Add(_customValidationAttribute);
IEnumerable<ModelValidator> validators =
base.GetValidators(metadata, context, customAttributes);
return validators;
}
}
I have registered it in the container :
// Register Custom Model Validation Provider
container.Register<DataAnnotationsModelValidatorProvider, CustomModelValidatorProvider>();
I have also created a DependencyResolverModelValidatorProvider
to get the provider for GetValidator
methods to be able to inject other lifetime scope instances:
public class DependencyResolverModelValidatorProvider
: DataAnnotationsModelValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(
ModelMetadata metadata, ControllerContext context,
IEnumerable<Attribute> attributes)
{
return GetProvider().GetValidators(metadata, context);
}
private static DataAnnotationsModelValidatorProvider GetProvider()
{
return (DataAnnotationsModelValidatorProvider)
DependencyResolver.Current.GetService(
typeof(DataAnnotationsModelValidatorProvider));
}
}
And finally I have replaced the current DataAnnotationsModelValidatorProvider
:
ModelValidatorProviders.Providers.Remove(
ModelValidatorProviders.Providers
.OfType<DataAnnotationsModelValidatorProvider>().First());
ModelValidatorProviders.Providers.Add(new DependencyResolverModelValidatorProvider());
Is this a good way to add custom injected validation attributes at runtime using Simple Injector?