C# FluentValidation – why we’re using it

A bit of background

I’ve been working in the C# world for a few months now. While the code is very similar to Java,the culture around open source could not be more different.  Where open source as business as usual in the Java & Javascript worlds, it’s very much exceptional circumstances only in the .Net one.  It took a bit of an extra push from myself to convince a client they should be looking at Fluent Validation for their validation needs, but I’m fairly certain (and more importantly they’re fairly certain) it was the right idea.

Fluent Validation

Fluent validation is an apache 2 licensed library that’s just moved from codeplex to github.  It enabled developers to code validation rules in a fluent manner and apply them to models.  In contrast to many modern validation approaches where the rules are declaratively mixed up with the models themselves using attributes (or annotations in Java parlance) fluent validation very firmly separates the models from the rules and has you define Validator classes instead.  Like this:

Simple!

The scenario

Their requirements are not exactly simple, but not particularly odd either.  They’ve got a large legacy code base that encapsulated a bunch of business logic, validation and data access.  They’re gradually migrating away from it because it’s slow and difficult to maintain, which is a pretty common scenario.  Due to the way the code base has evolved and the varying requirements they’re attempting to fulfill there are now four different ways into the database. To be clear, that’s four different implementations of their domain model and bindings to the underlying SQL schema.   Oh, and of course there are also custom validation rules coded by individual clients in various places and ways, not to mention that many of the rules for one entity depend on data from another. Currently, the default ‘always-apply’ rules are only in one place – the slow and inflexible legacy components.

The solution to all this is to extract the validation rules out of the legacy components and create a modern, fast and re-usable validation library that is data layer agnostic and can support configurable rule-sets.

Why Fluent Validation?

The main reason was flexibility.  We needed something that could attack such a wide variety of use cases it had to be able to validate anything in any context.  Fluent Validation fitted the bill

Other reasons included:

  • Speed of development – it’s really easy to work with.
  • Decoupled rules and models – meaning we could write multiple (and possibly conflicting, don’t ask) rule-sets against the same models.  In fact, enabling customers to write their own validators was pretty trivial exercise (see a future post on this)
  • Speed of execution – the rules are immutable objects meaning you can create them once and cache them.  When the rules are part of the model you’re needlessly setting them up every time.  This is not a problem when working with one simple entity, but quickly becomes a performance problem when you’re working with multiple complex validators over 50,000 rows. Benchmarking showed that we saved considerable time doing this – one import went from 12 minutes to 1 minute when we started caching validators.
  • Ability to work with odd relationships and dependent entities – many of the entities we work with have dependencies on other things in the system, even though they’re not ‘formally’ related.  With fluent validation we could write validators that handle this easily.

2 Comments

  1. vven

    “saved considerable time doing this – one import went from 12 minutes to 1 minute when we started caching validators”.. How are you caching validators?

    • Tom

      We created some sort of ValidatorFactory class that would lazily create validators as needed. It’d only create them once and because they were stateless be able to supply them to subsequent requests without re-creating them.

      I wish I could remember more detail, but shorty after that post I changed jobs. Hence no post two!

Leave a Reply