There is a new framework in the NHibernate Contrib project named NHibernate.Validator. The project began as port of the java Hibernate.Validator project and is started by Dario Quintana. This framework allows you to validate objects in a similar way to other validation frameworks except that it has out of the box integration with the NHibernate's entity lifecycle. This means that you can configure it to do validation on entity insert/updates. The integration with NHibernate is not required however.

You can specify the validation rules either as property/field attributes directly in the code or in a separate xml file with a schema similar to that used in NHibernate mapping files.

Example:

public class User
{
  public virtual int Id
  {
      get { return id; }
  }

  [NotEmpty, NotNull]
  public virtual string UserName
  {
      get { return userName; }
      set { userName = value; }
  }

  [Email]
  public virtual string Email
  {
      get { return email; }
      set { email = value; }
  }

  [Past]
  public DateTime CreatedDate
  {
    get { return createdDate; }
    set { createdDate = value; }
  }

  [Min(18, Message="You are to young!")]
  public int Age
  {
    get { return age; }
    set { age = value; }
  }

  [CreditCardNumber]
  public string CreditCardNumber
  {
    get { return creditCardNumber; }
    set { creditCardNumber = value; }
  }
  
  ///... 
}

If you don't like to clutter your code with attributes you can use the xml config option, example:

<nhv-mapping xmlns="urn:nhibernate-validator-1.0">
  <class name="NHibernate.Validator.Demo.Winforms.Model.Customer, NHibernate.Validator.Demo.Winforms">    
    <property name="FirstName">
      <not-empty/>
      <not-null/>
    </property>    
   
    <property name="Email">
      <email/>
    </property>

    <property name="Zip">
      <pattern  regex="^[A-Z0-9-]+$" message="Examples of valid matches: 234G-34DA | 3432-DF23"/>
      <pattern  regex="^....-....$" message="Must match ....-...."/>
    </property>    
    
  </class>  
</nhv-mapping>

Personally I can barley stand the NHibernate xml mapping files (don't like to poke around in xml files that much) so I think I prefer the attribute version. But it is nice to have this option. It makes it possible to validate objects in third party assemblies that you do not have the code for. There are many more validators than the ones used above and it is very easy to create custom validators.

You can configure the validation engine in code or in app/web.config, this is how you can do it in code:

NHVConfiguration nhvc = new NHVConfiguration();
nhvc.Properties[Environment.ApplyToDDL] = "false";
nhvc.Properties[Environment.AutoregisterListeners] = "true";
nhvc.Properties[Environment.ValidatorMode] = "UseAttribute";
nhvc.Mappings.Add(new MappingConfiguration("NHibernate.ValidatorDemo.Model", null));

ValidatorEngine validator = new ValidatorEngine();
validator.Configure(nhvc);

Since NHibernate.Validator uses the event listener system I think you have to use NHibernate 2.0 if you want the NHibernate integration. To validate an object you simply use the Validate function, here is a simple example (using MonoRail):

public void Create([DataBind("user")] User user)
{
  InvalidValue[] errors = validator.Validate(user);

  if (errors.Length > 0)
  {
    Flash["errors"] = errors;
    RedirectToAction("index");
  }
  else
  {
    repository.Create(user);
  }
}

And here is the view:

<div>
    <h2>Create user</h2>    
    
    ${Html.FormToAttributed("Home", "Create", {@id: "create-form"})}
    
    <p>    
        <label for="UserName">UserName:</label>
        ${Form.TextField("user.UserName")}
        
        <label for="UserName">Email:</label>
        ${Form.TextField("user.Email")}
        
        ${Html.SubmitButton("Submit")}
    </p>
            
    ${Html.EndForm()}
    
    
    <?brail if IsDefined("errors"): ?>
        <ul>
        <?brail for error in errors: ?>
            <li>${error.PropertyName}: ${error.Message}</li>    
        <?brail end ?>
        </ul> 
    <?brail end ?>
</div>

This is of course a very simple example. You probably want to have the error message after each field and some client based validation. I think I will do another post about trying to integrate NHiberante Validator with JQuery validation.

If you want to try NHibernate validator and do not want to build it from the trunk there is a 1.0 alpha release available on sourceforge. The release contains a WinForms examples that shows how to integrate it with the WinForms error provider system.