The S#arp framework: the duplicate entity validator

In the last post I promise that we’d talk about the EntityDuplicateChecker and that’s what we’re going to look at today. As we’ll see, this class is used by the custom NH validators that you can find in the SharpArch.Core.NHibernateValidator. The EntityDuplicateChecker implements the IEntityDuplicateChecker, which looks like this:

The EntityDuplicateChecker’s responsibility is to search for an entity with the same business signature as the IEntityWithTypedId instance that was passed in and that has a different Id.The current implementation of this interface is not really complicated since it relies on getting all the properties used in the business signature (which you can get by calling EntityWithTypedId’s GetSignatureProperties method) and adding a restriction for each to the ISession that is used for interacting with the database.

As you might expect (if you’ve been following along), the ISession is obtained by using the NHibernateSession.Current property which we’ve met in one of the latest posts. Now, even though you can use this class directly in your code, the truth is that you’ll probably end up using the custom HasUniqueDomainSignatureAttribute (if you’re using NH Validator for your domain validation, that is). Whenever you need to add a custom NH Validation rule, you need to add (at least) two classes: one new custom attribute and a new validator class. Let’s start with the custom attribute…

The S#arp framework introduces the HasUniqueDomainSignatureAttribute, which is really simple and looks like this:

This interface’s only objective is to let you get or set the error message that should be shown when there’s an error. Another interesting thing (from the previous snippet) is the use of the ValidatorClassAttribute. This is used to indicate the type of the validator class that is really responsible for performing the validation of that value. In this case,validation is performed by the HasUniqueDomainSignatureValidator class,which implements the mandatory IValidator interface. Here’s the current code for this class:

public class HasUniqueDomainSignatureValidator : NHibernate.Validator.Engine.IValidator { public bool IsValid(object value) { IEntityWithTypedId<int> entityToValidate = value as IEntityWithTypedId<int>; Check.Require(entityToValidate != null, "This validator must be used at the class level of an " + "IdomainWithTypedId<int>. The type you provided was " + value.GetType().ToString());

As you can see, the class has only one method which relies on the service locator for getting a valid instance of the IEntityDuplicateChecker that is responsible for validation. If you look at the source code, you’ll see that there are other pairs attribute/validator for validating specific types of database keys (you have one pair for strings and another for Guids, so use those instead of the general one I’ve shown if you’re using a strings or a Guids for keys).

Don’t forget that to use this custom validation attribute, you need to register the EntityDuplicateChecker with the ServiceLocator. If you don’t, validation won’t work!