13 thoughts on “IDataErrorInfo and FluentValidation

  1. chillfrie says:

    Good post, I think the ViewModel code has been put where the CodeBehind code should be?

  2. Szymon says:

    Great thing 🙂

  3. Mike says:

    Great tutorial! This is by far the most elegant solution for WPF validation. I was already using fluent validation with asp.net mvc, but I didn’t know how to integrate it with wpf. Thank you!

  4. Hugues Moisan-Plante says:

    Hi Brette!

    I’m late to the party but your tutorial is very helpful!

    I have a question regarding this part: “In real life the the IDataErrorInfo implementation would reside in some sort of base ViewModel class.”

    I’m using Prism so I’m guessing that I should derive BindableBase to implement IDataErrorInfo then derive my ViewModels from that?

    When doing that, how do I set up the Validator in the base class?

    Is it something like:

    [Dependency]
    public AbstractValidator Validator { get; set; }

    I’m hoping that would let Unity inject the correct Validator type in the derived ViewModel class?

    I’m new to MVVM so any input is appreciated!

    Thanks!

    • Hugues Moisan-Plante says:

      It looks like my angle brackets got removed when posting!

      I asked about AbstractValidator with “this.GetType().Name” inside the angle brackets.

      Thanks!

    • brettedotnet says:

      Thanks for your comments. I am also using Prism on a current project and you are correct in that you would derive from BindableBase or NotificationObject if you are using more recent builds of Prism. The question of dependency injection of the validators can be tricky. I will outline my approach that I have had with some success.

      ValidationManager
      Introduce a new object called a ValidationManager. This object should be injected into your base ViewModel implementation. The role of this object is to associate the correct validator with your ViewModel instance. This method has a method named Initialize(IViewModelBase viewModel). This method will use ServiceLocation to lookup up the correct Validator object in Unity using the passed in ViewModel’s type information. So something like this.

      public Initialize(IViewModel viewModel)
      {
      viewModel.Validator = ServiceLocator.Current.GetInstance(typeof(IValidator), viewModel.GetType().Name);
      }

      For this to work you will need to register a named dependency with Unity.

      Now in your base ViewModels constructor you can do something like this.

      public ViewModelBase(IValidationManager validationManager){ ValidationManager.Initialize(this);}

      Once this line of code executes your viewModels Validator property will be handed an instance of the correct validator object.

      Also its worth nothing that ValidationManager is what I used to control all validation type things from code. This keeps that messy stuff out of my viewModels. For example the ValidationManager can publish EventAggregator notifications to the rest of the app if other screens, controls care to know about validation changes etc.

      Hope this helps,

      Brette

      • Hugues Moisan-Plante says:

        Hi Brette,

        Thank you for your detailed explanation.

        I tried hard implementing it but hit a snag. Here is what I tried:

        I made a validator class for my View Model, inheriting from the generic AbstractValidator. I also created the validationManager as you suggested. Then I created a ViewModelBase class that’s derived from BindableBase. I implemented IDataErrorInfo in that class and made my View Model inherit from it.

        However, while implementing the logic in the indexer for IDataErrorInfo, I found out that the FluentValidation method Validator.Validate that takes an instance of a VM and the propertyName to validate is in fact an extension method that is only supported on the generic version of IValidator. The non-generic version of IValidator only takes the object instance and therefore will only validate all of the properties at once.

        Now, I’m not quite sure how to register the generic version with my validator classes in the Unity container (in my BootStrapper) and how to resolve them using the service locator in the ValidationManager.Initialize().

        Any insight would be appreciated!

      • brettedotnet says:

        Hey Hugues,

        Lets do this over email. We can exchange code and communicate a bit better that way. I have run into this same limitation and there are a few ways you can deal with it. Shoot me a mail at Brette@Brette.net

Leave a comment