Saved post: A framework for Validation and Business Rules in C#

Saved post: A framework for Validation and Business Rules in C#
Photo by Joshua Aragon / Unsplash

I’ve been pretty lax on my blog posting for the last three months, primarily because some other things in life had higher priority. In the mean time I’ve received a few comments on when I will resume blogging again. Now that things have normalized a bit hopefully I can get back to blogging more frequently now. For all those who left comments while I was away, thank you for continuing to visit my blog (it feels good to know I have somewhat a following :P) and I’ll try to keep the posts coming.

[Edit: There was a minor mistake in the EntityValidator class which added validation messages to the ValidationResult even when a validation rule returned true.]

[Edit2: Somehow something got screwed up while pasting the code snippets to the post and extra line breaks were added. I’ve fixed the code snippets for now and have removed the scrollbars. Also see my latest post to get the source code for this post.]

So for the first post after a long hiatus, I choose to tackle Validation and Business Rules. Both Validation and Business Rules are common requirement for enterprise projects, but you’d be surprised how common it is even for the most trivial applications. I’ve come across myriad ways of implementing a Validation or Business Rule framework, most of them which are quite complicated. Since I am such a fan of simplicity, in this post I’ll describe my take on Validation and Business rules and build a simple framework for providing both functionality for DDD applications.

Note: This post relies heavily on a previous post on implementing the Specification pattern. If you have not read that post, I would urge you to read this post: Implementing Repository and Specification patterns using Linq.

Validations Rules and Business Rules… the Differences

To build a common framework for validation logic and business rules it’s important to provide a distinction between then. Both are quite different in their intent but share a common pattern that can sometimes get confusing and you can end up mistaking validation logic for business rules.

In my opinion, and I say it in that way because others may approach it quite differently;

Validation Rules are re-usable parts of logic that perform validation on an entity, of which that validation can range from simple data integrity to a state validation, and whose primarily goal is to validate the entity before an action is taken on that entity.

We all know those simple data validation rules that say; First Name cannot be null or empty or Username must be more than 6 characters with no special characters and has to have at least one numeric and one upper case character. I classify these as data integrity validations. They check the integrity of the data in a entity, usually entered by the user, to make sure that an action on an entity with invalid data is not taken place.

Then there is another class of validations that look very similar to Business Rules but really fall under the classification of Validations. I term these as business validations that most often validate the sate of an entity. For example; If an Order entity’s customer has a preferred status of Silver, the the sum total of the Order amount along with all pending payments from the customer cannot be more than $10,000.

In short the above validation checks to make sure that the total credit on the customer’s order does not go beyond $10,000. That is classified as a state validation because when the customer submits the order the system should validate the order against the above validation rule to ensure that the Customer entity’s total pending payments does not exceed above a certain value, causing that entity to go into an invalid sate. If the validation fails, then the application should report back to the customer at the time of submitting the order.

Now you might be asking why is the above rule not a business rule but termed as a validation rule…

In my opinion, again a personal observation that can differ from others, a business rule is;

Business Rules are re-usable parts of logic that perform actions on an entity, based on certain conditions that are evaluated against the entity.

Short and sweet. Business Rules do not perform any validations, rather they perform actions based on conditions that is defined by the rule itself.

This distinction between validations and business rules is important because in the business rules world, the assumption is that data and state validations have already taken place and now business actions need to be performed based on the data and state of the entity. Business rules themselves do not stop an action from happening, such as saving of the Order, like validations but rather perform actions as defined by the business.

Validation and Business Rules as Specifications

A common theme that I have noticed in the applications I have built is that both validations and business rules sometimes have rules that are really Specifications. For example, there could be a business rule that checks if a client account is a classified as High Profile customer. This classification of High Profile can be defined using the Specification pattern which can then be re-used not only for querying for High Profile customers, but also in the business rule that performs an action when an order is saved for a High Profile customer (perhaps puts the order in the urgent fulfillment queue).

Using specifications to define the rules for validation and business rules is quite powerful, which allows further re-usability and using the composite specification pattern it gives the ability to compose multiple specifications to define rules for validations and business actions.

Since I have already covered the Specification pattern in the following posts, I’m not going to go into much detail with regards to implementing the Specification pattern. If you haven’t read my previous posts before, you should read them before continuing as the framework will heavily depend on the implementation of the Specification pattern.

Defining the interfaces:

Okay, enough talk… time to show some code. Lets start with the basic building blocks. The first thing to do is to define the interfaces for the validation and business rules:

IValidationRule interface:

/// <summary>
/// Provides a contract that defines a validation rule that provides validation logic  for an entity.
/// </summary>
/// <typeparam name="TEntity">The type of entity this validation rule is applicable for.</typeparam>

public interface IValidationRule<TEntity>
{
    /// <summary>
    /// Gets the message of the validation rule.
    /// </summary>
    string ValidationMessage { get; }

    /// <summary>
    /// Gets a generic or specific name of a property that was validated.
    /// </summary>
    string ValidationProperty { get; }

    /// <summary>
    /// Validates whether the entity violates the validation rule or not.
    /// </summary>
    /// <param name="entity">The <typeparamref name="TEntity"/> entity instance to validate.</param>
    /// <returns>Should return true if the entity instance is valid, else false.</returns>
    bool Validate(TEntity entity);
}

IBusinessRule interface:

/// <summary>
/// An interface that defines business rule for an entity instance.
/// </summary>
/// <typeparam name="TEntity">The type of entity that this business rule evaluates.</typeparam>

public interface IBusinessRule <TEntity>
{
    /// <summary>
    /// Evaulates the business rule against an entity instance.
    /// </summary>
    /// <param name="entity"><typeparamref name="TEntity"/>. The entity instance against which
    /// the business rule is evaulated.</param>

    void Evaluate(TEntity entity);
}

The IValidationRule interface simply has an Validate method and provides two properties to get the validation message and the validated property. The IBusinessRule interface simply provides a method to run the business rule evaluation on the provided entity via the Evaluate method.

Default implementations of IValidationRule and IBusinessRule

Now that I have the interfaces defined, the next step is to provide base implementations of those interfaces. Since I want to use the specification pattern as the base for the Validation and Business rules, below is a abstract class that provides a base for creating validation and business rules that use specifications for evaluating the rules:

/// <summary>
/// Base implementation that uses <see cref="ISpecification{TEntity}"/> instances that provide the logic to check if the
/// rule is satisfied.
/// </summary>
/// <typeparam name="TEntity"></typeparam>

public abstract class SpecificationRuleBase<TEntity>
{
    #region fields
    private ISpecification<TEntity> _rule; //The underlying rule as a specification.
    #endregion

    #region .ctor
    /// <summary>
    /// Default Constructor.
    /// Protected. Must be called by implementors.
    /// </summary>
    /// <param name="rule">A <see cref="ISpecification{TEntity}"/> instance that specifies the rule.</param>
    protected SpecificationRuleBase(ISpecification<TEntity> rule)
    {
        Guard.Against<ArgumentNullException>(rule == null, "Expected a non null and valid ISpecification<TEntity> rule instance.");
        _rule = rule;
    }
    #endregion

    #region methods
    /// <summary>
    /// Checks if the entity instance satisfies this rule.
    /// </summary>
    /// <param name="entity">The <typeparamref name="TEntity"/> insance.</param>
    /// <returns>bool. True if the rule is satsified, else false.</returns>
    public bool IsSatisfied(TEntity entity)
    {
        Guard.Against<ArgumentNullException>(entity == null,
            "Expected a valid non-null entity instance against which the rule can be evaulated.");
        return _rule.IsSatisfiedBy(entity);
    }
    #endregion
}

The SpecificationRuleBase class has a protected constructor that expects a ISpecification that is used in the IsSatisfied method to evaluate if the rule is satisfied. Now that I have a base class that uses specifications, I can then create concrete implementations of the IValidationRule and IBusinessRule interfaces:

ValidationRule Class

/// <summary>
/// Implements the <see cref="IValidationRule{TEntity}"/> interface and inherits from the
/// <see cref="SpecificationRuleBase{TEntity}"/> to provide a very basic implementation of an
/// entity validation rule that uses specifications as underlying rule logic.
/// </summary>
/// <typeparam name="TEntity"></typeparam>

public class ValidationRule<TEntity> : SpecificationRuleBase<TEntity>, IValidationRule<TEntity>
{
    #region fields
        private readonly string _message;
        private readonly string _property;
    #endregion

    #region .ctor
        /// <summary>
        /// Default Constructor.
        /// Creates a new instance of the <see cref="ValidationRule{TEntity}"/> class.
        /// </summary>
        /// <param name="message">string. The validation message associated with the rule.</param>
        /// <param name="property">string. The generic or specific name of the property that was validated.</param>
        /// <param name="rule"></param>
        public ValidationRule(ISpecification<TEntity> rule, string message, string property) : base(rule)
        {
            Guard.Against<ArgumentNullException>(string.IsNullOrEmpty(message), "Please provide a valid non null value for the validationMessage parameter.");
            Guard.Against<ArgumentNullException>(string.IsNullOrEmpty(property), "Please provide a valid non null value for the validationProperty parameter.");
            _message = message;
            _property = property;
        }
    #endregion

    #region methods
        /// <summary>
        /// Gets the message of the validation rule.
        /// </summary>
        public string ValidationMessage
        {
            get { return _message; }
        }
    
        /// <summary>
        /// Gets a generic or specific name of a property that was validated.
        /// </summary>
        public string ValidationProperty
        {
            get { return _property; }
        }
    
        /// <summary>
        /// Validates whether the entity violates the validation rule or not.
        /// </summary>
        /// <param name="entity">The <typeparamref name="TEntity"/> entity instance to validate.</param>
        /// <returns>Should return true if the entity instance is valid, else false.</returns>
        public bool Validate(TEntity entity)
        {
            return IsSatisfied(entity);
        }
    #endregion
}

Since the ValidationRule class inherits from the SpecificationRuleBase, in it’s constructor it expects a ISpecification instance that represents the underlying rule that is checked while validating the entity. This class can now be used like so:

public void ChangePassword(User user, string newPassword)
{
    Specification<string> moreThan5 = new Specification<string>(x => x.Length > 5);
    Specification<string> hasUpper = new Specification<string>(x => HasUpperCase(x));
    Specification<string> hasNumeric = new Specification<string>(x => HasNumeric(x));

    ValidationRule<string> validatePassword = new ValidationRule<string>(moreThan5 & hasUpper & hasNumeric,
        "The password provided does not match the password restriction policy. Your new password must be" +
        "at least 6 characters long with one upper case and one numeric character",
        "New Password");

    if (!validatePassword.Validate(newPassword))
    {
        //Show the error...
    }
}

public bool HasUpperCase(string value)
{
    foreach (var character in value)
    {
        if (char.IsUpper(character)) return true;
    }
    return false;
}

public bool HasNumeric(string value)
{
    foreach (var character in value)
    {
        if (char.IsUpper(character)) return true;
    }
    return false;
}

The above is just an example, obviously the correct thing to do would be to get the the ValidationRule instances via a IoC container or a validation rules collection.

BusinessRule Class

/// <summary>
/// Implements the <see cref="IBusinessRule{TEntity}"/> interface and inherits from the
/// <see cref="SpecificationRuleBase{TEntity}"/> to provide a implementation of a business rule that
/// uses specifications as rule logic.
/// </summary>
/// <typeparam name="TEntity"></typeparam>

public class BusinessRule < TEntity >: SpecificationRuleBase < TEntity > , IBusinessRule < TEntity > where TEntity: class {
    #region fields
    private Action < TEntity > _action; //The business action to undertake.
    #endregion

    #region ctor
    /// <summary>
    /// Default Constructor.
    /// Creates a new instance of the <see cref="BusinessRule{TEntity}"/> instance.
    /// </summary>
    /// <param name="rule">A <see cref="ISpecification{TEntity}"/> instance that acts as the underlying
    /// specification that this business rule is evaulated against.</param>
    /// <param name="action">A <see cref="Action{TEntity}"/> instance that is invoked when the business rule
    /// is satisfied.</param>
    public BusinessRule(ISpecification < TEntity > rule, Action < TEntity > action): base(rule) {
        Guard.Against < ArgumentNullException > (action == null, "Please provide a valid non null Action<TEntity> delegate instance.");
        _action = action;
    }
    #endregion

    #region methods
    /// <summary>
    /// Evaulates the business rule against an entity instance.
    /// </summary>
    /// <param name="entity"><typeparamref name="TEntity"/>. The entity instance against which
    /// the business rule is evaulated.</param>
    public void Evaluate(TEntity entity) {
        Guard.Against < ArgumentNullException > (entity == null,
            "Cannot evaulate a business rule against a null reference.");
        if (IsSatisfied(entity))
            _action(entity);
    }
    #endregion
}

The BusinessRule class is not very complicated either. In it’s constructor it accepts a ISpecification that forms the underlying rule that it evaluates against the entity and also a delegate of Action<T>, which is called when the rule evaluates to true.

Below is an example of how a BusinessRule could be used:

public void SaveOrder(Order order) {
    //Snip... Save order to database...
    BusinessRule < Order > urgeDeliveryForHighProfileOrders = new BusinessRule < Order > (IsHighProfileOrder(), MarkUrgent);
    urgeDeliveryForHighProfileOrders.Evaluate(order);
}
private void MarkUrgent(Order order) {
    //Snip... Mark the order in the database urgent...
}
public ISpecification < Order > IsHighProfileOrder() {
    return new Specification < Order > (x => x.Customer.Orders.Sum(order => order.TotalValue) > 100000);
}

Again, just like the example for validation, the above is just for illustration. Ideally the business rule would be injected via a IoC.

Performing multiple validations or business rule evaluations:

As interesting the above examples may be, they are not really real-word representations. In the real world you would have multiple validations being performed on the entity and perhaps multiple business rules evaluated against the entity.

A EntityValidator to perform validations

The first step is to define a IEntityValidator interface. This interface will be used to define the contract of an Evaluator. Since the EntityValidator will run multiple validation rules at once, there needs to be a way for the validator to report back what all validations failed. For this two data structures are created; the ValidationError structure and ValidationResult class:

ValidationError

 /// <summary>
 /// Represents a validation error from a <see cref="IEntityValidator{TEntity}.Validate"/> method
 /// call.
 /// </summary>
 public struct ValidationError {
     #region fields
     public readonly string Message;
     public readonly string Property;
     #endregion
     #region ctor
     /// <summary>
     /// Default Constructor.
     /// Creates a new instance of the <see cref="ValidationError"/> data structure.
     /// </summary>
     /// <param name="message">string. The validation error message.</param>
     /// <param name="property">string. The property that was validated.</param>
     public ValidationError(string message, string property) {
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty("message"),
             "Please provide a valid non null string as the validation error message");
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty("property"),
             "Please provide a valid non null string as the validation property name");
         Message = message;
         Property = property;
     }
     #endregion
     #region methods
     /// <summary>
     /// Overriden. Gets a string that represents the validation error.
     /// </summary>
     /// <returns></returns>
     public override string ToString() {
         return string.Format("({0}) - {1}", Property, Message);
     }
     /// <summary>
     /// Overridden. Compares if an object is equal to the <see cref="ValidationError"/> instance.
     /// </summary>
     /// <param name="obj"></param>
     /// <returns></returns>
     public override bool Equals(object obj) {
         if (obj.GetType() != typeof (ValidationError)) return false;
         return Equals((ValidationError) obj);
     }
     /// <summary>
     /// Overriden. Compares if a <see cref="ValidationError"/> instance is equal to this
     /// <see cref="ValidationError"/> instance.
     /// </summary>
     /// <param name="obj"></param>
     /// <returns></returns>
     public bool Equals(ValidationError obj) {
         return Equals(obj.Message, Message) && Equals(obj.Property, Property);
     }
     /// <summary>
     /// Returns the hash code for this instance.
     /// </summary>
     /// <returns>
     /// A 32-bit signed integer that is the hash code for this instance.
     /// </returns>
     /// <filterpriority>2</filterpriority>
     public override int GetHashCode() {
         unchecked {
             return (Message.GetHashCode() * 397) ^ Property.GetHashCode();
         }
     }
     /// <summary>
     /// Equality operator.
     /// </summary>
     /// <param name="left"></param>
     /// <param name="right"></param>
     /// <returns></returns>
     public static bool operator == (ValidationError left, ValidationError right) {
         return left.Equals(right);
     }
     /// <summary>
     /// Inequality operator.
     /// </summary>
     /// <param name="left"></param>
     /// <param name="right"></param>
     /// <returns></returns>
     public static bool operator != (ValidationError left, ValidationError right) {
         return !left.Equals(right);
     }
     #endregion
 }

The ValidationError struct is a immutable data structure that simply accepts the error message and the property that was validated.

ValidationResult

 /// <summary>
 /// Contains the result of a <see cref="IEntityValidator{TEntity}.Validate"/> method call.
 /// </summary>
 public class ValidationResult {
     #region fields
     private readonly List < ValidationError > _errors = new List < ValidationError > ();
     #endregion
     #region properties
     /// <summary>
     /// Gets wheater the validation operation on an entity was valid or not.
     /// </summary>
     public bool IsValid {
         get {
             return _errors.Count == 0;
         }
     }
     /// <summary>
     /// Gets an <see cref="IEnumerable{ValidationError}"/> that can be used to enumerate over
     /// the validation errors as a result of a <see cref="IEntityValidator{TEntity}.Validate"/> method
     /// call.
     /// </summary>
     public IEnumerable < ValidationError > Errors {
         get {
             foreach(var error in _errors)
             yield
             return error;
         }
     }
     #endregion
     #region methods
     /// <summary>
     /// Adds a validation error into the result.
     /// </summary>
     /// <param name="error"></param>
     public void AddError(ValidationError error) {
         _errors.Add(error);
     }
     /// <summary>
     /// Removes a validation error from the result.
     /// </summary>
     /// <param name="error"></param>
     public void RemoveError(ValidationError error) {
         if (_errors.Contains(error))
             _errors.Remove(error);
     }
     #endregion
 }

The ValidationResult class merely wraps a collection of ValidationError instances and provides a way to add, remove and enumerate over the validation errors in the result. It also has a IsValid property that basically returns if the validation operation was successfull or not as a whole.

So now that we have the data structure that will be used to report back the validation results, below is the IEntityValidator interface

  /// <summary>
  /// Interface implemented by different flavors of validators that provide validation
  /// logic on domain entities.
  /// </summary>
  /// <typeparam name="TEntity"></typeparam>
  public interface IEntityValidator < TEntity > {
      /// <summary>
      /// Validates an entity against all validations defined for the entity.
      /// </summary>
      /// <param name="entity">The <typeparamref name="TEntity"/> to validate.</param>
      /// <returns>A <see cref="ValidationResult"/> that contains the results of the validation.</returns>
      ValidationResult Validate(TEntity entity);
  }

Using this interface I can now create a abstract class with common logic to add and remove IValidationRule instances, which can then be used by specific implementations to provide validation evaluators:

 public abstract class EntityValidatorBase < TEntity >: IEntityValidator < TEntity > where TEntity: class {
     #region fields
     //The internal dictionary used to store rule sets.
     private readonly Dictionary < string, IValidationRule < TEntity >> _validations = new Dictionary < string, IValidationRule < TEntity >> ();
     #endregion
     #region methods
     /// <summary>
     /// Adds a <see cref="IValidationRule{TEntity}"/> instance to the entity validator.
     /// </summary>
     /// <param name="rule">The <see cref="IValidationRule{TEntity}"/> instance to add.</param>
     /// <param name="ruleName">string. The unique name assigned to the validation rule.</param>
     protected void AddValidation(string ruleName, IValidationRule < TEntity > rule) {
         Guard.Against < ArgumentNullException > (rule == null,
             "Cannot add a null rule instance. Expected a non null reference.");
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty(ruleName),
             "Cannot add a rule with an empty or null rule name.");
         Guard.Against < ArgumentException > (_validations.ContainsKey(ruleName),
             "Another rule with the same name already exists. Cannot add duplicate rules.");
         _validations.Add(ruleName, rule);
     }
     /// <summary>
     /// Removes a previously added rule, specified with the <paramref name="ruleName"/>, from the evaluator.
     /// </summary>
     /// <param name="ruleName">string. The name of the rule to remove.</param>
     protected void RemoveValidation(string ruleName) {
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty(ruleName), "Expected a non empty and non-null rule name.");
         _validations.Remove(ruleName);
     }
     /// <summary>
     /// Validates an entity against all validations defined for the entity.
     /// </summary>
     /// <param name="entity">The <typeparamref name="TEntity"/> to validate.</param>
     /// <returns>A <see cref="ValidationResult"/> that contains the results of the validation.</returns>
     public ValidationResult Validate(TEntity entity) {
         ValidationResult result = new ValidationResult();
         _validations.Keys.ForEach(x => {
             IValidationRule < TEntity > rule = _validations[x];
             if (!rule.Validate(entity))
                 result.AddError(new ValidationError(rule.ValidationMessage,
                     rule.ValidationProperty));
         });
         return result;
     }
     #endregion
 }

This base class can now be used in the following way to define a OrderValidator that validates order classes, which can then be used in a OrdersService to validate order entites before saving them to the repository:

 public class OrdersService {
     private IEntityValidator < Order > _ordersValidator;
     private IRepository < Order > _orderRepository;
     public OrdersService(IEntityValidator < Order > orderValidator, IRepository < Order > orderRepository) {
         _ordersValidator = orderValidator;
         _orderRepository = orderRepository;
     }
     public void SaveOrder(Order order) {
         ValidationResult validateResult = _ordersValidator.Validate(order);
         if (!validateResult.IsValid)
             throw new ValidationException(validateResult);
         _orderRepository.Save(order);
     }
 }
 public class OrderValidator: EntityValidatorBase < Order > {
     public OrderValidator() {
         AddValidation("BackOrderValidation",
             new ValidationRule < Order > (
                 new Specification < Order > (order => order.OrderDate > DateTime.Now.AddDays(-1)),
                 "Order date cannot be backdated.", "OrderDate"));
         AddValidation("OrderItemsCountValidation",
             new ValidationRule < Order > (new Specification < Order > (order => order.Items.Count() > 0),
                 "Order must contain at least one item", "Order Items"));
         AddValidation("HighValueOrderForSilverCustomers",
             new ValidationRule < Order > (
                 OrderSpecifications.LowValueCustomer() & OrderSpecifications.HighOrderValue(),
                 "Cannot place a high value order. Please apply for Gold membership", "Order"));
     }
 }
 public static class OrderSpecifications {
     public static Specification < Order > LowValueCustomer() {
         return new Specification < Order > (order => order.Customer.CustomerClass < CustomerClass.Platinum);
     }
     public static Specification < Order > HighOrderValue() {
         return new Specification < Order > (order => order.TotalValue > 40000);
     }
 }

A BusinessRuleEvaluator to perform business rule evaluations

Similar to the above IEntityValidator, below is an interface for a IBusinessRuleEvaluator that evaualtes a set of business rules for an entity.

The interface is kept simple by intention because all that is required from the evaluator is to evaluate all the rules within it. Since we don’t require any feedback on results the Evaluate method does not return anything. Following the same patter as EntityValidatorBase, I have defined a abstract BusinessRuleEvaluatorBase class that provides protected methods to allow implementors to add / remove business rules from the evaluator.

 public abstract class BusinessRulesEvaulatorBase < TEntity >: IBusinessRulesEvaluator < TEntity > where TEntity: class {
     #region fields
     //The internal dictionary used to store rule sets.
     private readonly Dictionary < string, IBusinessRule < TEntity >> _ruleSets = new Dictionary < string, IBusinessRule < TEntity >> ();
     #endregion
     #region methods
     /// <summary>
     /// Adds a <see cref="IBusinessRule{TEntity}"/> instance to the rules evaluator.
     /// </summary>
     /// <param name="rule">The <see cref="IBusinessRule{TEntity}"/> instance to add.</param>
     /// <param name="ruleName">string. The unique name assigned to the business rule.</param>
     protected void AddRule(string ruleName, IBusinessRule < TEntity > rule) {
         Guard.Against < ArgumentNullException > (rule == null,
             "Cannot add a null rule instance. Expected a non null reference.");
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty(ruleName),
             "Cannot add a rule with an empty or null rule name.");
         Guard.Against < ArgumentException > (_ruleSets.ContainsKey(ruleName),
             "Another rule with the same name already exists. Cannot add duplicate rules.");
         _ruleSets.Add(ruleName, rule);
     }
     /// <summary>
     /// Removes a previously added rule, specified with the <paramref name="ruleName"/>, from the evaluator.
     /// </summary>
     /// <param name="ruleName">string. The name of the rule to remove.</param>
     protected void RemoveRule(string ruleName) {
         Guard.Against < ArgumentNullException > (string.IsNullOrEmpty(ruleName), "Expected a non empty and non-null rule name.");
         _ruleSets.Remove(ruleName);
     }
     /// <summary>
     /// Evaulates all business rules registred with the evaluator against a entity instance.
     /// </summary>
     /// <param name="entity">The <typeparamref name="TEntity"/> instance against which all
     /// registered business rules are evauluated.</param>
     public void Evaulate(TEntity entity) {
         Guard.Against < ArgumentNullException > (entity == null,
             "Cannot evaulate rules against a null reference. Expected a valid non-null entity instance.");
         _ruleSets.Keys.ForEach(x => EvaulateRule(x, entity));
     }
     /// <summary>
     /// Evaulates a business rules against an entity.
     /// </summary>
     /// <param name="ruleName">string. The name of the rule to evaulate.
     /// <param name="entity">A <typeparamref name="TEntity"/> instance against which the business
     /// rules are evaulated.</param>
     private void EvaulateRule(string ruleName, TEntity entity) {
         Guard.Against < ArgumentNullException > (entity == null, "Cannot evaulate a business rule set against a null reference.");
         if (_ruleSets.ContainsKey(ruleName)) {
             _ruleSets[ruleName].Evaluate(entity);
         }
     }
     #endregion
 }

Now this base class can be used to define custom business rule evaluators. I have extended the example for the EntityValidatorBase to show how the BusinessRuleEvaluatorBase can be used to evaluate a set of business rules in the OrdersService:

public class OrdersService {
    private IEntityValidator < Order > _ordersValidator;
    private IRepository < Order > _orderRepository;
    private IBusinessRulesEvaluator < Order > _businessRules;
    public OrdersService(IEntityValidator < Order > orderValidator, IBusinessRulesEvaluator < Order > businessRules, IRepository < Order > orderRepository) {
        _ordersValidator = orderValidator;
        _businessRules = businessRules;
        _orderRepository = orderRepository;
    }
    public void SaveOrder(Order order) {
        ValidationResult validateResult = _ordersValidator.Validate(order);
        if (!validateResult.IsValid) throw new ValidationException(validateResult);
        _orderRepository.Save(order);
        _businessRules.Evaulate(order);
    }
}
public class OrderBusinessRules: BusinessRulesEvaulatorBase < Order > {
    public OrderBusinessRules() {
        AddRule("PlaceHighValueOrdersInImmediateQueue",
            new BusinessRule < Order > (OrderSpecifications.HighOrderValue(), PlaceOrderInImmediateProcessingQueue));
        AddRule("SetBackOrderIfItemsNotInStock",
            new BusinessRule < Order > (new Specification < Order > (x => HasItemThatIsNotInStock(x)),
                SetOrderAsBackorder));
    }
    private void PlaceOrderInImmediateProcessingQueue(Order order) {
        //Snip...
    }
    private bool HasItemThatIsNotInStock(Order order) {
        //Snip...
    }
    private void SetOrderAsBackorder(Order order) {
        //Snip...
    }
}

You can now use the above as a framework for developing implementations of Validation and Business Rules logic in your applications, using Expressions and Specifications as light weight rule evaluators.

One final note, I haven’t yet uploaded the code for this on google code as yet. I’m re-structuring the current codebase of Rhinestone and removing all framework level stuff to a separate project so that those components can be used independently in your applications without having to use Rhinestone. I’ll update this post once I have the new project setup on CodePlex (Since they now support SVN natively, I’m giving CodePlex a second chance).