1

I am having some trouble trying to integrate FluentValidation with Unity.

I have a factory class

  public class UnityValidatorFactory : FluentValidation.ValidatorFactoryBase
{
    private readonly IUnityContainer _container;

    public UnityValidatorFactory()
    {
        _container = null;
    }

    public UnityValidatorFactory(IUnityContainer container)
    {
        _container = container;
    }

    public override FluentValidation.IValidator CreateInstance(Type validatorType)
    {
        return _container.Resolve(validatorType) as FluentValidation.IValidator;
    }

}

The problem is that it won't instantiate in the data class

 public class Payment : IValidatableObject
{
    private readonly IValidator _validator = new PaymentValidator();

    public string paymentType { get; set; }
   //etc

    public Payment(IValidatorFactory validatorFactory)
    {
        **//ValidatorFactory is always null!**
        _validator = validatorFactory.GetValidator(typeof(Payment));
    }
}

This is the code I am trying to use to register the factory class with unity

container.RegisterType<IValidatorFactory, UnityValidatorFactory>(new ContainerControlledLifetimeManager());

However the factory is always null. Any idea what I am doing wrong?

jazza1000
  • 4,099
  • 3
  • 44
  • 65

1 Answers1

0

My suggestion would be the next.

Create all your validators and implement the next interface, name it as: IModelValidator

public interface IModelValidator
{
}

//example of a validator class
public class MyModelValidator : AbstractValidator<MyModel>, IModelValidator
{
    public MyModelValidator ()
    {
        CascadeMode = CascadeMode.StopOnFirstFailure;

        RuleFor(x => x.yourField)
            .NotNull()
            .NotEmpty()
            .WithMessage("You need to enter yourField");
    }
}

//this is to register all your interfaces on the container
void RegisterValidators(IUnityContainer container)
{
   var type = typeof(IValidator<>);
   var validators = AssemblyScanner.FindValidatorsInAssemblyContaining<IModelValidator>();

   validators.ForEach(validator => container.RegisterType(validator.InterfaceType, validator.ValidatorType));
}

//Integrating with MVC, this should be do in your Global.asax when you create your container

public static ConfigureFluentValidation(IUnityContainer container)
{
   var fluentValidationModelValidatorProvider = new FluentValidationModelValidatorProvider(new UnityValidationFactory(container));
   //disables the implicit required validator being added for both the DataAnnotationsModelProvider, as well as the FluentValidationModelValidatorProvider.
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;


    fluentValidationModelValidatorProvider.AddImplicitRequiredValidator = false;
    //adds the new model validator provider to the list of model validator providers used by the MVC framework.

 ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);         
 }

Now in your controller method when you post the information to be validated you will see if you leave yourField empty that ModelState.IsValid has a false value

Zinov
  • 3,817
  • 5
  • 36
  • 70