Specification for domain and NHibernate database queries, without Linq

by andrei 15. September 2008 19:32

Until Linq2NHibernate is ready for production, here is a method for keeping the specification logic encapsulated even if the domain code is different than the database query code.

Here is the specification interface, where I added the EnsureThatWillBeSatisfiedBy method:

public interface ISpecification<T>
{
  bool IsSatisfiedBy(T recipient);
  ICriteria EnsureThatWillBeSatisfiedBy(ICriteria criteria);
}

I am also using an extension for ICriteria:

public static class CriteriaExtension
{
  public static ICriteria EnsureItWillSatisfy<T>(this ICriteria criteria, ISpecification<T> specificationToSatisfy)
  {
    return specificationToSatisfy.EnsureThatWillBeSatisfiedBy(criteria);
  }
}

The specification looks like this:

class ProductAvailableSpecification: ISpecification<Product>
{
  public bool IsSatisfiedBy(Product product)
  {
    return product.ActiveYN
           && product.ExpirationDate > DateTimeService.Now
           && product.RemainingQuantity > 0;
  }

  public ICriteria EnsureThatWillBeSatisfiedBy(ICriteria criteria)
  {
    return criteria
      .Add(Expression.Eq("IsActiveYN", 1))
      .Add(Expression.Gt("ExpirationDate", DateTimeService.Now))
      .Add(Expression.Gt("RemainingQuantity", 0));
  }
}

Here is how it can be used in the domain:

ProductAvailableSpecification _productAvailableSpecification = new ProductAvailableSpecification();
public bool CheckFirstProduct()
{
  Product product = _products[0];
  if (_productAvailableSpecification.IsSatisfiedBy(product))
    return true;

  return false;
}

and here is how it can be used in the repository to load only products that are satisfying the specification:

ProductAvailableSpecification _productAvailableSpecification = new ProductAvailableSpecification();
public IList<Product> GetProductsSatisfyingCriteria() { return Repository<Product>.CreateCriteria() .EnsureItWillSatisfy(_productAvailableSpecification) .List<Product>(); }
The specification logic is still written twice, but it is encapsulated in the same class and it is easy to maintain.

 

 

Enjoy programming!

 

DDD

I am putting together a set of concept lists for the main programming techniques, which should help developers learning or using them to be more efficient. Here are the techniques in progress:

Please feel free to leave any comments or suggestions which could make these lists more useful for everyone.

 

 

Also, if you are interested in learning these techniques you can try the developer training modules.

Again, please feel free to leave any comments or suggestions which could make the training modules more useful for everyone. We are having great results with them at Akcedo (so they really work), but they can always be improved. Also, if you would like to use the modules or are already using them and you want to discuss about the process feel free to comment and ask questions here.

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0