This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.
NHibernate Validator is the standard way to implement custom validation of entities – that is, validation other than just based on the table schema definition. It is available from Nuget (https://nuget.org/packages/NHibernate.Validator) and as source code from GitHub (https://github.com/darioquintana/NHibernate-Validator).
This is about the actual integration of Validator with NHibernate; it has some gotchas that you should be aware of. Here’s a simple guide.
Let’s suppose you have a User class:
You want to be sure that:
The Name and Email properties have values and have at most 50 characters;
The Email property is a valid email address;
The Birthday is in the past.
Let’s forget about the mappings, they should be very easy to create. Let’s focus instead on NHibernate Validator, and, following what seems the current trend on .NET, loquacious (or fluent) configuration:
You can see that be created a validation configuration instance and we populated it with a validation definition for the User class. You could as well create your own class that inherits from ValidationDef<User> and place all validation logic there.
Next, we need to integrate NHibernate Validator with NHibernate:
If you are curious, NHibernate Validator will add listeners for the PreInsert and PreUpdate events, which will be fired when the session is about to save or update some entity.
And that’s it! Now, validation will occur in two distinct ways:
Explicit, if you call ValidatorEngine.Validate:
Implicit, if you try to save an invalid entity:
Using a shared engine provider (the NHibernate.Validator.Cfg.Environment.SharedEngineProvider instance) is required, because the listeners have no other way of getting your configured ValidatorEngine. You are free – and advised to, actually – to create your own provider, by implementing NHibernate.Validator.Event.ISharedEngineProvider in the way that best suits your needs, perhaps using IoC to retrieve a single instance.