December 2008 Blog Posts

Getting back to working on Rhinestone has made me take a closer look at the domain model that I had setup. Since it’s been a while since I last touched Rhinestone’s code base, I started off refactoring some of the infrastructure code that I had included in Rhinestone which has not moved out into its own project NCommon.

While refactoring I noticed a potential issue in the Project entity. In a previous post where I described the domain model for Rhinestone, the definition of a project owner and project members was factored as a interface IUser. Basically the intent was to not have Rhinestone worry about user authentication, authorization and management, and have those services plugged in as domain level services. Simply put, Rhinestone would be able to play nice with any authentication and account management system, as long as that system implemented the IUserService interface to provide Rhinestone IUser instances.

The potential issue that I identified was around the creation and retrieval of Project instances. Lets take the following scenario where there is a project description page in Rhinestone which shows the name and description of the project. Along with it displays the names of the owner and members of the project.

Following is part of the ER Model of RhinestoneDB:

image

It’s quite apparent that the application will store the username of the IUser instance that is the owner of the project, and as for members, those are stored in ProjectMembers table along with the ProjectID and username of each member.

That allows RhinestoneDB to not have hard dependencies on a particular User Account system Similarly, here is part of the domain model:

image 

The dilemma is that when a Project instance is being retrieved from the database, how and who should set the appropriate IUser instance to the project’s Owner property and should the Members collection be populated with IUser instances???

To inject Domain Services or NOT to inject Domain Services:

One of the more popular discussions that arise from DDD forums and articles is should domain services be injected as part of Domain entities via dependency injection?

Take for example the above scenario, one way to instantiate IUser instances when getting a Project instance from the database is to have a IUsersService injected into a Project instance which then allows the Project instance to get concrete IUser instances via the IUsersService.

At first glance this makes sense, but then creates an additional issue where lets say when I am creating a new, i.e. transient, Project entity I either have to provide a IUsersService instance manually or use a IoC container to instantiate a Project instance.

Now I don’t know about anyone else, but anytime I start to think about about delegating domain entity creation to IoC containers my skin cringes. It makes me feel like I’ve added an additional layer of complexity and lost a level of flexibility in my domain model and tied it down to always be dependent on a container for entity creation. In my opinion having to rely on IoC containers for resolving domain entity instances violates the purity of a domain layer. This line of thought starts another argument about the Anemic Domain Model anti-pattern. You can read more about this in Martin Fowlers excellent post: Anemic Domain Model. I completely agree with Martin’s, and Evan’s by extension, concerns on putting all logic into Domain Services and leaving the domain entities quite devoid of logic, which then tend to represent an over glorified DTO layer.

Nevertheless, I still believe that using Dependency Injection pattern on Domain entities is a bad thing. It’s a code smell according to me. It starts to bleed a opinionated creation pattern which forces the upper level layers that rely on IoC containers to create domain instances. I know I’m repeating myself here…

Anyways, on the flip side domain entities need to perform logic and sometimes this logic relies on some domain services to provide some logic that may be external to the entity. Let me take an example from the current project I am working on, it’s a Engineering Project Management client application that allows engineers to build a project cost / estimate and also contains rules regarding what equipment or items can be used when building a certain type of system.

One of the rules behind this application is that when the user is building a certain type of project, when adding a specific piece of equipment, we need to ensure that when added a equipment requisition order is generated for that piece of equipment.

To that end we have a domain entity called Project (aggregate root), and contains a method AddEquipment (I’m simplifying the domain model here a bit because the model is quite more complex than that) that takes in a Equipment entity instance. Now the above piece of logic squarely falls within the scope of the Project entity. But the Project entity should not know anything about how to create a equipment requisition order because that would violate the Single Responsibility rule.

So we create a IEquipmentRequisitionService that handles creating requisition orders for projects, which it does so by creating an instance of a EquipmentRequisition order and saving it to a repository. The EquipmentRequisition in turn handles setting the appropriate properties based on the equipment being requisitioned, and it itself could require external services for additional info or functionality.

Anyways, that takes care of the Single Responsibility rule, and neatly encapsulates the logic of equipment requisition into a simple service. But the problem becomes how does a Project instance get a hold of an IEquipmentRequisitionService instance. Heres the model:

image

Removing the logic from the Project entity and moving up to another service is following the Anemic Domain Model pattern, and its what usually happens. The Domain Service layer becomes a huge procedural repository that reduces any usefulness of the domain model.

Making the IEquipmentRequisitionService injected into Project instances doesn’t make sense because this service may not be used at all times, remember a requisition order is created only for certain projects. So why force the Project to always have the IEquipmentRequisitionService injected into it at all times.

Enter the Service Locator Pattern… Our savior:

In my opinion, the Dependency Injection pattern has become so popular along with the various IoC containers that sometimes we forget that the Service Locator pattern also exists and is quite useful in such scenarios.

Having domain entities use a Service Locator to get instances of the Domain Services they need, and at the time they need them, is perfectly acceptable in my opinion. It maintains dependency decoupling, ensures contract driven programming, doesn’t violate the Single Responsibility principal and does not force a creation pattern on consumers of the domain model. You could always under the layers of the Service Locator use your favorite IoC container to create instances of the Domain Service that was requested.

The only issue that arises with using a Service Locator to resolve domain services by domain entities is that you can introduce infrastructure concerns within the domain model. You can always create a generic service locator or use the now accepted Common Service Locator to get around creating a hard dependency on a specific Serivce Locator / IoC Container implementation.

Well those are my thoughts on the use of Domain services within Domain entities, but I’d be very interested in hearing other thoughts on this issue. So far this approach to makes the most amount of sense.

Back to Rhinestone, the problem at hand:

Alright, back to Rhinestone. Well now that I’ve settled my reasons for not having the IUsersService injected into Project instances, naturally you might think that I’ll use the service locator pattern to get instances of IUsersService inside Project.

Well not really. Looking at the project entity, it seems that in it’s current state, it would need the IUsersService only at the time of retrieval from the database. After that both AddMember, RemoveMember and the Owner property accept IUser instances, which the application can get via the IUsersService.

So the ideal would be to somehow get appropriate IUser instances when the project is being retrieved from the database, via NHibernate. One of the ways we can handle this is via custom user types in NHibernate by implementing IUserType interface. The IUserType allows NHibernate to convert a value retrieved from the database to custom type that you define, and vice versa.

This seems like a perfect solution, as I could implement a custom ICompositeUserType that reads the username values stored in the database, get an instance of IUsersService via a service locator, and then convert the value to a ICompositeUser instance by calling the IUsersService.FindUserByName().

Next post will go into detail how to implement a ICompositeUserType in NHibernate, and more interestingly how to map a custom user type to a collection in your domain entity.


I get some excellent questions and comments sometimes for previous posts from time to time, and I feel replying back as a comment makes the question and answer less discoverable and a hindrance to having a good conversation about certain topics. So I’ve decided to answer some of these comments regularly in a regular post called Answering some comments.

1. Comment on the Unit of Work pattern (in NCommon):

So the first comment comes from an anonymous commenter on the Unit of Work pattern I had posted a while back, Implementing a persistence ignorant Unit of Work framework.

I agree that TransactionScope (and the underlying transaction) is not supported by all data source providers. However, support is far from "spotty" in my opinion. Most ADO.NET providers I've worked with support it including Oracle. There is even support with transactional file systems like NTFS. I also am not keen on mixing transactions in with the UnitOfWork although in your implementation, transaction management appears to be the only thing it is responsible for doing.

First off the reason I mentioned that support for TransactionScope and the transaction enlistment is spotty because while mainstream databases do have good support for it, non-main stream may not. In my experience third-party implementations for transaction enlistment have their kinks in them that cause un-expected exceptions. Things may have changed though, since I haven’t worked on projects that have used SqlLite or My SQL recently, so if things have improved I stand corrected.

As far as support for TransactionScope in the UnitOfWorkScope implementation in NCommon, if you are using an underlying provider that supports transaction enlistment then UnitOfWorkScope will honor the TransactionScope that it is running under.

Regarding mixing transaction management in the Unit of Work, well a big part of a Unit of Work is transaction management. The responsibility of the unit of work pattern is two fold:

  • Manage all changes made to entities within a unit of work as a single logical unit of operation.
  • Require that changes made to entities succeed as a whole.

The first point refers to the responsibility of tracking all changes you make to entities originating from a unit of work. This is key because to consider operations that fall under a unit of work, the implementation must be able to track any changes to entities that fall under its scope.

The second point, by extension of first, ensures that changes made to entities and tracked by the unit of work, succeed as a whole or not accepted at all. This is the transaction management part of the unit of work pattern.

Now in NCommon, the UnitOfWork, as well as UnitOfWorkScope, are largely concerned with transaction management because the responsibility if tracking changes to entities is delegated to your implementation of IUnitOfWork. This is designed intentionally because you could employ any change tracking mechanism in your application. Taking ORM frameworks for example, NHibernate’s ISession provides change management functionality (not exactly change tracking), Linq to SQL’s DataContext does change tracking and so does Entity Framework’s ObjectContext. These underlying infrastructure components provide change management functionality which is then provided to the UnitOfWork and UnitOfWorkScope instances as implementations of IUnitOfWork.

So yes it may seem that the UnitOfWork class is overly concerned with transaction management, which is because the change management part is hooked in via implementations of the IUnitOfWork interface.

2. Guidance on POCO with Linq To SQL and Entity Framework:

Justin commented on my Update on NCommon post:

Once again awesome stuff! Any advice on creating provider agnostic poco's? NHibernate supports this pretty well but L2S and EF probably need a bit of hackery.

Let me just start by saying if you are interested in a good domain model that is primarily POCO and infrastructure agnostic, stay away from Entity Framework. I don’t mean to put Entity Framework down, but in v1.0 its not something you want to even consider if you are employing good domain driven design in your application.

There are just too many things in Entity Framework that make the implementation of a true POCO domain model very difficult if not impossible. But if you are stuck having to use Entity Framework, which is the case if your IT org mandates Microsoft technologies only, then my recommendation is to treat the Entity Framework as a data access layer.

I would create a well defined set POCO domain entities and then in the domain service layer use entity framework to retrieve data and then populate the POCO domain entities. That way your domain model remains infrastructure agnostic. You’ll loose things like lazy loading and a level of change tracking but that’s a small price to pay to keep your domain free from infrastructure corruption.

I have a future post on my opinions on the Entity Framework coming soon.

As for Linq to SQL… I would have wished Microsoft’s data team to realize that the current state of Linq to SQL provides a better ORM story than Entity Framework. You can and certainly should use external XML mapping files with Linq to SQL. Again you will loose things like lazy loading because to support lazy loading your references entities and associations should use EntityRef or EntitySet respectively. Again, a small price to pay.

Ian Cooper has a very good overview on how to go about setting up Linq To SQL to use external mapping files, which works well when using POCO approach: http://codebetter.com/blogs/ian_cooper/archive/2008/03/09/previous-architecting-linq-to-sql-applications-part-5.aspx. Actually the entire series from Ian is a very interesting read and may provide some insight to Linq to SQL.

Linq to SQL’s XML mapping file is not as difficult to grasp than the Entity Model’s schemas and is at par in my opinion with NHibernate. One of the major drawbacks to Linq to SQL is that it is tied down to SQL Server. If you’re using Oracle or any other database, Linq to SQL out. Also Linq to SQL cannot model complex inheritance and does not support Value types, two major features of a well defined domain.

In the end my recommendation would be to go with NHibernate or LLBGenPro if you can, failing that if it’s a choice between Linq to SQL and Entity Framework…. if you care about DDD or a good domain design I would recommend Linq to SQL.


Since my last post on the NCommon project, I’ve been looking at using NCommon as the base framework for Rhinestone. Jumping back into Rhinestone I realized that I first need an implementation of RepositoryBase and UnitOfWork for NHibernate. I decided to go ahead and create implementations of RepositoryBase and UnitOfWork for NHibernate, Linq To SQL and Entity Framework (that last one giving me the most head ache). While developing these implementations, some changes were made to NCommon.

Here are some of the changes.

  • Save on IRepository changed to Add and Update

While implementing RepositoryBase for Linq to SQL and Entity Framework, it was obvious that the single Save method won’t work. Both don’t have a way to identify new entities on their own and rely on the consumer to tell weather to insert or update the entity.

In some ways this makes sense because some complex entities may have unique ways to identify a new entity, but there is almost always a single identifying property or field that marks the state of an entity. NHibernate deals with this scenario by using the unsaved-value attribute either on the Id element or on the version element. That allows NHibernate to easily identify new entities as opposed to existing ones.

Since both Linq and EF don’t have any such smarts in them, the only way to maintain infrastructure ignorance on the base class was to split Save into two separate functions Add and Update.

For a brief while I was considering adding an additional interface, called IEntityStateProvider with one method IsNew(TEntity entity), that would be injected into the LinqToSqlRepository or EFRepository and would be used to identify if an entity is new or not. That didn’t fly because that would mean that if I had a complex domain with a multitude of entities, I didn’t want to sit around and create IEntityStateProvider implementations for each entity just to find its effin state.

The other approach I was toying around is to use something like a Func<TEntity entity, bool> delegate that the repository could call to check if the entity being passed in Save is new or not. If this delegate was not specified then it would use the Contains extension to query the underlying IQueryable to see if that entity already exists. That mean that if the delegate was not specified, every time Save is called the database would be hit with a useless Exists call.

I just ended up splitting the damn method to Add and Update to keep things simple.

  • Added a With method to allow eager loading of entities

One of the things that was missing from the original IRepository interface was to allow a way to specify eager loaded entities. Almost all ORM’s provide a way to specify entities to eager load when evaluating a query. The challenge was to decide the method signature.

NHibernate provides a method called Expand that takes in a string that represents the path of the entity to eager load.

Similarly, Entity Framework has a method called Include that again takes in a string that represents the path of the entity to eager load.

Obviously, Linq to SQL had to do it differently. It uses a class called DataLoadOptions that has  method LoadWith It instead accepts an expression. This DataLoadOptions class is then associated with the DataContext :)

Actually I liked the way Linq to SQL uses the Expression<Func<TEntity entity, objhect>> to specify what entities to re-load. It provides a compile time check where as in NHiberate and Entity Framework, if the underlying property name was changed you’d end up getting errors.

The method signature of With method in IRepository is:

  • With(Expression<Func<TEntity entity, object>> path)

Obviously since both NHibernate and Entity Framework require a string path, I had to convert the expression into a string represented path. To do this, I added a MemberAccessPathVisitor, inheriting from ExpressionVisitor, to NCommon. Calling Visit() on this class will analyze the expression and build a path string which can be obtained using the Path property of the visitor.

This MemberAccessPathVisitor is made public in case you need to create an implementation of IRepository for a ORM framework that expects eager loaded paths as strings.

  • Added Detach, Attach, Refresh methods on IRepository

I got a comment on one of my previous posts to consider adding Detach, Attach and Refresh methods on the UnitOfWork. Although I disagree that those methods belong on the UnitOfWork, they do make sense on the repository. The Unit of Work’s role is to act as a singe unit boundary where all actions within that unit are accepted or not accepted. It really should not be concerned with the state of a entity.

Instead, those methods completely make sense at the Repository level because the Repository should most definitely concerned with the state of an entity. You would use the Repository to retrieve and update entities, it would make sense to use the Repository to attach, detach and also refresh entities.

I’ve added these methods to the IRepository<TEntity> interface and also provided implementations for them in the NHibernate, Linq To Sql and Entity Framework implementations. Since Linq To SQL doesn’t really allow Detaching entities, entities are detached when the DataContext goes out of scope, calling Detach on the Linq to SQL implementation throws a NotSupportedException.

  • Added sub namespaces to provide logical separation

Another suggestion I received to move the separate patterns into their own namespaces. At first I was opposed to the idea because I didn’t believe there was too much complexity there… I was wrong. While developing the different implementations for RepositoryBase, I realized that providing a logical separation via namespaces would provide less clutter.

So here’s the structure now;

  • Repository and UnitOfWork are under NCommon.Data namespace
  • Specifications is under NCommon.Specifications namespace
  • Business and Validation rules are under NCommon.Rules namespace
  • Storage classes (Application, Local, Session) are under NCommon.Storage namespace. The Storage class has been renamed to Store so that there is no clash between namespace and class name.
  • New NCommon.Extensions namespace to contain with common extensions.
  • New NCommon.Expressions namespace contains the ExpressionVisitor class and future implementations for ExpressionVisitor to help process expressions.

Beyond the above changes there are some bug fixes that I found while developing the implementations for RepositoryBase and UnitOfWork. I’ll be posting a how-to post on how to (duh) use the implementations of RepositoryBase and UnitOfWork.

Keep an eye out on future blog posts on Rhinestone where I’m going to start using NCommon to flesh out the project.

As always, if you have any suggestions on NCommon please add a comment. 


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).


I have created a new project on CodePlex called it NCommon. This CodePlex project hosts the entire source code of all the various frameworks and patterns that I have talked about on this blog.

Previously the source was coupled with Rhinestone, the bug reporting app I am working on. While that seamed fine for a while, I started to realize that all the framework level stuff could be bundled up as a separate library that could then be used in multiple applications. Hence the creation of the NCommon project.

I intend to put all common framework level stuff into this project and try to keep it as infrastructure agnostic as possible. NCommon currently has source for:

I have gotten rid of the generic IoC wrapper implementation from the library as it doesn’t seem necessary anymore with the rally behind the Common Service Locator project. I will also be adding implementations of the Repository and Unit of Work patterns for Linq to SQL, Entity Framework and NHibernate(*) soon

I have some more ideas on what could go into NCommon, but that’s for future posts. If anone have any suggestions or ideas on what other common functionality they would like to add to NCommon or if you would like to contribute to NCommon I’d be more more than willing to listen.

* I’m not sure what the state of Linq to NHibernate is right now so the implementation of RepositoryBase for NHibernate may be delayed until the NHiberante can provide a stable implementation of their Linq provider.