Try fast search NHibernate

02 November 2009

Validation Abstraction: Custom

If you have read this post you know I’m having some psychological problem at work: multi-personality.

My dear friend Fabio-NHV said me: hey man! I have a very good OSS validation framework strongly recommended if you are validating entities you are using with NHibernate.

And I said: Cool!! but your framework is only an option for me… soon or later I’ll use something else and, btw, I need to mix the validation done by your framework with my BL and/or UI validation.

The IEntityValidator

The IEntityValidator is part of uNhAddIns because José asked me how I’m abstracting the validation stuff from my application, during the implementation of the ChinookMediamanager example (the same happened with the IGuyWire and, a year ago, with the CpBT and Gustavo).

public interface IEntityValidator
{
bool IsValid(object entityInstance);
IList<IInvalidValueInfo> Validate(object entityInstance);
IList<IInvalidValueInfo> Validate<T, TP>(T entityInstance, Expression<Func<T, TP>> property) where T : class;
IList<IInvalidValueInfo> Validate(object entityInstance, string propertyName);
}
public interface IInvalidValueInfo
{
Type EntityType { get; }
string PropertyName { get; }
string Message { get; }
}

any good validation-framework should give me the way to implement an adapter for, at least, these methods.

The implementation for NHibernate.Validator

We having an implementation of IEntityValidator in uNhAddIns… by the way, in an application in production, I’m using a more simple implementation:

public class NhVEntityValidator : IEntityValidator
{
private readonly ValidatorEngine validatorEngine;

public NhVEntityValidator(ValidatorEngine validatorEngine)
{
this.validatorEngine = validatorEngine;
}

#region Implementation of IEntityValidator

public bool IsValid(object entityInstance)
{
return validatorEngine.IsValid(entityInstance);
}

public IList<IInvalidValueInfo> Validate(object entityInstance)
{
InvalidValue[] iv = validatorEngine.Validate(entityInstance);
return
new
List<IInvalidValueInfo>(
from invalidValue in iv
select (IInvalidValueInfo) new InvalidValueInfo(invalidValue));
}

#endregion
}

public class InvalidValueInfo : IInvalidValueInfo
{
private readonly InvalidValue iv;

public InvalidValueInfo(InvalidValue iv)
{
this.iv = iv;
}

#region Implementation of IInvalidValueInfo

public Type EntityType
{
get { return iv.EntityType; }
}

public string PropertyName
{
get { return iv.PropertyName; }
}

public string Message
{
get { return iv.Message; }
}

#endregion
}

The Usage
As you can imagine the usage is simple. Where you need the IEntityValidator you must inject it:
public UsuarioParticularNuevoService(
    IDaoFactory factory,
IUserSessionContext context,
IMailSender mailSender,
IMailMaker mailMaker,
IEntityValidator entityValidator)

and then simply use it

public IInvalidValueInfo[] Register(UsuarioNuevoInfo usuarioInfo)
{
var usuario = GetUsuario(usuarioInfo);

AddPais(usuario);
AddDireccion(usuario, usuarioInfo);
AddTelefono(usuario, usuarioInfo);
AddNewsletter(usuario, usuarioInfo);
AddNegocio(usuario);

var errors = validator.Validate(usuario);

if (errors != null && errors.Count > 0)
return errors.ToArray();

usuarioDao.SaveOrUpdate(usuario);
mailSender.Send(GetMailMaker(usuarioInfo, usuario).Make());
return new IInvalidValueInfo[0];
}

The chunk, of the IoC’s configuration (in this case Castle.Windsor), in my dear IGuyWire look like:

ValidatorEngine validatorEngine = ConfigureNHibernateValidatorEngine();

container.Register(Component.For<ValidatorEngine>().Instance(validatorEngine));
container.Register(Component.For<ISharedEngineProvider>().ImplementedBy<SharedEngineProvider>());
NHibernate.Validator.Cfg.Environment.SharedEngineProvider =
container.Resolve<ISharedEngineProvider>();
container.Register(Component.For<IEntityValidator>().ImplementedBy<NhVEntityValidator>());

Options

In uNhAddIns you can find two more options, for the IEntityValidator, implemented for ValidationApplicationBlock and for DataAnnotation (thanks to José Romaniello for his implementation).

1 comment:

  1. Castle.Validator is also there.
    Thanks to Roelof Blom.

    ReplyDelete