I build trading systems for investment banks.

ASP.NET MVC, TDD and Fluent Validation

Yesterday I wrote about ASP.NET MVC, TDD and AutoMapper, and how you can use them together in a DDD application. Today I thought I would follow up and explain how to apply these techniques to another important (but boring) part of any web application: user input validation.

To achieve this, we are using Fluent Validation, a validation framework that lets you easily set up validation rules using a fluent syntax:

As usual, the controller is pretty thin, delegating all responsibility (including performing any required validation) to an application service that handles new user registration. If validation fails, all our controller has to do is catch an exception and append the validation messages contained within to the model state to tell the user any mistakes they made.

The UserRegistrationForm validator is injected into the application service along with any others. Just like AutoMapper, we can now test both the controller, validator and application service separately.

You can even inject dependencies into the validator and mock them out for testing. For example, in this app the validator calls an IUsernameAvailabilityService to make sure the chosen username is still available.

Testing the user registration service

This validation code is now completely isolated, and we can mock out the entire thing when testing the application service:

Cool to find other kiwis who are into this! Whats up with the Fluent interface for building a user seems like overkill and it would possibly allow the user object to be invalid before saving it to the repository? Does the repository validate, or at this point is it up to Nhibernate to kick in with mappings and constraints?

I agree with the overall flow, but I’m not convinced whether your ViewModels (UserRegistrationForm) should be in the ApplicationServices (UserRegistrationService) layer.

What if your ApplicationServices layer is shared by more than one client? For example, in addition to your Web MVC client, you want to add a Win console app. If this were the case, you ApplicationServices layer would have to know about ViewModels from both client apps, which seems smelly to me.

Martin – good question. In that case you would put a formal API in place that returns API-specific DTOs (effectively the same as a view model, without any specific UI in mind). For example, Twitter’s “get user” method might return the user’s details combined with their last ten tweets.

Then each client queries/send commands to the API, and maps its responses to their own UI-specific view models.

There should hopefully be a blog post about this (API-driven applications) in the next month or three :)

You don’t consider throwing exceptions for validation a bit heavy handed? Considering exceptions should really only occur in “exceptional” circumstances and the cost associated with throwing and catching them?