August 2008 Blog Posts

IoC containers are great at reducing complex dependencies in an application and the Dependency Injection design pattern has existed for quite some time. Although IoC containers are quite popular in the Java world but it’s taken some time for good IoC containers to emerge for .Net. Even MS has jumped on the bandwagon and is showing some love for IoC by giving us Unity as an IoC container.

Today there are many, many IoC containers to choose from. That’s the one thing I really like about the ALT.Net community, varied implementations and depth of choice that allows us to pick what implementation really fits our need. We have excellent IoC containers like Castle Windsor, StructureMap, NInject, Spring.Net, Unity… the list goes on and on. You can take a look at Scott Hanselman’s list of IoC containers available for .Net to get an idea of the depth of choice available: List of .NET Dependency Injection Containers (IOC)

I have more or less settled for Castle Windsor as my choice of IoC container for my projects and have used it quite a lot but recently I have been interested in stuff that Jeremy Miller has been doing to StructureMap. Some of the deep functionality added to StructureMap and the ability to do some really neat logging and debugging is very interesting. The fluent interface of StructureMap is also quite clean and something I would really like to use since I’m quite sick of XML (I know Windsor has a fluent interface and am aware of Binsdor, Aynde’s awesome DSL implementation for specifying Windsor container configuration. I cannot use Binsor quite yet in our projects because of external dependencies to Boo and although Windsor has a pretty good fluent interface I like the idea of the Registry in StructureMap)

I have been toying around with the preview release, 2.4.9, of StructureMap and have been itching to try it out. But then I realized that I need a way to insulate my application from the IoC container choice I make, well since the application shouldn’t really have to know the concrete IoC container that will be used. All the application should care about is getting a IoC container component which provides Dependency Injection semantics.

Hence the need for a wrapper that the application will use as a generic IoC container. The wrapper will encapsulate the IoC container of our choice, allowing us to swap out IoC container implementations if we need to. So in this post I’m going to provide an implementation of this wrapper… ingeniously called IoC :)

Some foundation work before we defining the IoC wrapper:

Okay, before I start on the IoC wrapper, I need some infrastructure work done. Ideally when application starts, the IoC container is created and all components are registered at that time. This IoC container instance then is stored for the life time of the application. If our project is a web site then the IoC container instance should be stored in the HttpApplication. Now I must admit the thought of this component came from Aynde’s implementation of LocalData in Rhino Commons (https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/rhino-commons/Rhino.Commons.Clr/LocalDataImpl/LocalData.cs), but the LocalData implementation doesn’t allow me to store information on the HttpApplication level and uses ThreadStatic to store thread speciffic data.

That won’t work for me since I want to use something similar to LocalData to store the IoC container instance on either the application level, i.e. App Domain level if it’s a client app or the HttpApplication if its a web site, or at the thread / pre-request level. To tackle this scenario I started out by first implementing a Storage class:

   13     public abstract class Storage

   14     {

   15         #region methods

   16         /// <summary>

   17         /// Gets the data stored with the specified key in the storage

   18         /// </summary>

   19         /// <typeparam name="T">The type of data to get.</typeparam>

   20         /// <param name="key">object. The key that uniquely identifies the data to retrieve.</param>

   21         /// <returns>A <typeparamref name="T"/> instance or null if not found.</returns>

   22         public T Get<T>(object key)

   23         {

   24             throw new NotImplementedException();

   25         }

   26 

   27         /// <summary>

   28         /// Adds or updates the data specified with the key in the Storage

   29         /// </summary>

   30         /// <typeparam name="T">The type of data to add or update.</typeparam>

   31         /// <param name="key">object. The key that uniquely identifies the data being stored.</param>

   32         /// <param name="value"><typeparamref name="T"/>. The value to add or update.</param>

   33         public void Set<T>(object key, T value)

   34         {

   35             throw new NotImplementedException();

   36         }

   37 

   38         /// <summary>

   39         /// Checks whether the Storage contains data with the specified key.

   40         /// </summary>

   41         /// <param name="key">object. The unique key to check for.</param>

   42         /// <returns>True if data specified with the key was found, else false.</returns>

   43         public bool Contains(object key)

   44         {

   45             throw new NotImplementedException();

   46         }

   47 

   48         /// <summary>

   49         /// Removes the data specified with the key in Storage

   50         /// </summary>

   51         /// <param name="key"></param>

   52         /// <returns></returns>

   53         public void Remove(object key)

   54         {

   55             throw new NotImplementedException();

   56         }

   57 

   58         /// <summary>

   59         /// Removes all data in Storage

   60         /// </summary>

   61         public void Clear()

   62         {

   63             throw new NotImplementedException();

   64         }

   65         #endregion

   66     }

So the Storage class is an abstract class with standard methods for adding, removing and clearing items from the storage. The idea is that the client will request the type of storage that it wants to use and then use the above methods to manipulate the storage. The following properties tell the Storage class what type of Storage instance is the client expecting to use:

   15         #region properties

   16         /// <summary>

   17         /// Gets whether the current application is a web application.

   18         /// </summary>

   19         /// <value>bool. True if the current application is a web application.</value>

   20         public static bool IsWebApplication

   21         {

   22             get { return System.Web.HttpContext.Current != null; }

   23         }

   24 

   25         /// <summary>

   26         /// Gets a <see cref="Storage"/> implementation that can be used to store application

   27         /// sepcific data for the current thread / request.

   28         /// </summary>

   29         public static Storage Local

   30         {

   31             get

   32             {

   33                 return null;

   34             }

   35         }

   36 

   37         /// <summary>

   38         /// Gets a <see cref="Storage"/> instance that can be used to store application specific

   39         /// data for the applicatuion.

   40         /// </summary>

   41         public static Storage Application

   42         {

   43             get

   44             {

   45                 return null;

   46             }

   47         }

   48 

   49         /// <summary>

   50         /// Gets a <see cref="Storage"/> instance that can be used to store application sepcific

   51         /// data in the current session.

   52         /// </summary>

   53         public static Storage Session

   54         {

   55             get

   56             {

   57                 return null;

   58             }

   59         }

   60         #endregion

For now the properties return null and I have added a IsWebApplication properties that would allow consumers to and implementations of Storage to know the current application is a web site.

Now, the way I have implemented the Add, Remove, Clear methods on Storage is to add a abstract GetInternalHashtable method that will be implemented by specific implementations of the Storage class, in this case Application, Local and Session, and then the Hashtable returned by this method will then be manipulated in the Add, Remove, Clear methods. Below is the implementation of the methods:

  109  #region methods

  110         /// <summary>

  111         /// Gets the data stored with the specified key in <see cref="Storage"/>.

  112         /// </summary>

  113         /// <typeparam name="T">The type of data to get.</typeparam>

  114         /// <param name="key">object. The key that uniquely identifies the data to retrieve.</param>

  115         /// <returns>A <typeparamref name="T"/> instance or null if not found.</returns>

  116         public T Get<T>(object key)

  117         {

  118             if (UseLocking)

  119             {

  120                 lock (LockInstance)

  121                     return (T)GetInternalHashtable()[key];

  122             }

  123             return (T)GetInternalHashtable()[key];

  124         }

  125 

  126         /// <summary>

  127         /// Adds or updates the data specified with the key in <see cref="Storage"/>.

  128         /// </summary>

  129         /// <typeparam name="T">The type of data to add or update.</typeparam>

  130         /// <param name="key">object. The key that uniquely identifies the data being stored.</param>

  131         /// <param name="value"><typeparamref name="T"/>. The value to add or update.</param>

  132         public void Set<T>(object key, T value)

  133         {

  134             if (UseLocking)

  135             {

  136                 lock (LockInstance)

  137                     GetInternalHashtable()[key] = value;

  138             }

  139             else

  140                 GetInternalHashtable()[key] = value;

  141         }

  142 

  143         /// <summary>

  144         /// Checks whether the <see cref="AppStorage"/> contains data with the specified key.

  145         /// </summary>

  146         /// <param name="key">object. The unique key to check for.</param>

  147         /// <returns>True if data specified with the key was found, else false.</returns>

  148         public bool Contains(object key)

  149         {

  150             if (UseLocking)

  151             {

  152                 lock (LockInstance)

  153                     return GetInternalHashtable().ContainsKey(key);

  154             }

  155             return GetInternalHashtable().ContainsKey(key);

  156         }

  157 

  158         /// <summary>

  159         /// Removes the data specified with the key in <see cref="Storage"/>.

  160         /// </summary>

  161         /// <param name="key"></param>

  162         /// <returns></returns>

  163         public void Remove(object key)

  164         {

  165             if (UseLocking)

  166             {

  167                 lock (LockInstance)

  168                     GetInternalHashtable().Remove(key);

  169             }

  170             else

  171                 GetInternalHashtable().Remove(key);

  172         }

  173 

  174         /// <summary>

  175         /// Removes all data in <see cref="Storage"/>.

  176         /// </summary>

  177         public void Clear()

  178         {

  179             if (UseLocking)

  180             {

  181                 lock (LockInstance)

  182                     GetInternalHashtable().Clear();

  183             }

  184             else

  185                 GetInternalHashtable().Clear();

  186         }

  187         #endregion

  188 

  189         #region abstract members

  190         /// <summary>

  191         /// When overriden, tells whether the <see cref="Storage"/> uses locking when retrieving and setting values.

  192         /// </summary>

  193         protected abstract bool UseLocking { get; }

  194 

  195         /// <summary>

  196         /// Gets the object used by the <see cref="Storage"/> for locking when retrieving and setting values.

  197         /// </summary>

  198         protected abstract object LockInstance { get; }

  199 

  200         ///<summary>

  201         /// When overriden by a sub class, provides the internal Hashtable used to store and retrieve

  202         /// data.

  203         ///</summary>

  204         ///<returns></returns>

  205         protected abstract Hashtable GetInternalHashtable();

  206         #endregion

So the above methods first ask the implementation whether locking is required for thread synchronization, which would be required if you are manipulating at the application scope, i.e. App Domain or HttpApplication. If locking is required then it asks the implementation to provide a object that Storage can use for locking and then uses the Hashtable returned by the GetInternalHashtable method.

Now to bring Storage full circle the next step is to provide specific implementations of Storage that will be returned in Local, Application and Session properties. Below is the complete code for the Storage class and it’s implementation (Also available in Rhinestone’s source code).

Storage.cs

   25     public abstract class Storage

   26     {

   27         #region fields

   28         private static AppStorage _appStorage;

   29         protected static readonly object AppStorageLock = new object();

   30 

   31         private static LocalStorage _localStorage;

   32         protected static readonly object LocalStorageLock = new object();

   33 

   34         private static SessionStorage _sessionStorage;

   35         protected static readonly object SessionStorageLock = new object();

   36         #endregion

   37 

   38         #region properties

   39         /// <summary>

   40         /// Gets whether the current application is a web application.

   41         /// </summary>

   42         /// <value>bool. True if the current application is a web application.</value>

   43         public static bool IsWebApplication

   44         {

   45             get { return System.Web.HttpContext.Current != null; }

   46         }

   47 

   48         /// <summary>

   49         /// Gets a <see cref="Storage"/> implementation that can be used to store application

   50         /// sepcific data for the current thread / request.

   51         /// </summary>

   52         public static Storage Local

   53         {

   54             get

   55             {

   56                 if (_localStorage == null)

   57                 {

   58                     lock (LocalStorageLock)

   59                     {

   60                         if (_localStorage == null)

   61                             _localStorage = new LocalStorage();

   62                     }

   63                 }

   64                 return _localStorage;

   65             }

   66         }

   67 

   68         /// <summary>

   69         /// Gets a <see cref="Storage"/> instance that can be used to store application specific

   70         /// data for the applicatuion.

   71         /// </summary>

   72         public static Storage Application

   73         {

   74             get

   75             {

   76                 if (_appStorage == null)

   77                 {

   78                     lock (AppStorageLock)

   79                     {

   80                         if (_appStorage == null)

   81                             _appStorage = new AppStorage();

   82                     }

   83                 }

   84                 return _appStorage;

   85             }

   86         }

   87 

   88         /// <summary>

   89         /// Gets a <see cref="Storage"/> instance that can be used to store application sepcific

   90         /// data in the current session.

   91         /// </summary>

   92         public static Storage Session

   93         {

   94             get

   95             {

   96                 if (_sessionStorage == null)

   97                 {

   98                     lock (SessionStorageLock)

   99                     {

  100                         if (_sessionStorage == null)

  101                             _sessionStorage = new SessionStorage();

  102                     }

  103                 }

  104                 return _sessionStorage;

  105             }

  106         }

  107         #endregion

  108 

  109         #region methods

  110         /// <summary>

  111         /// Gets the data stored with the specified key in <see cref="Storage"/>.

  112         /// </summary>

  113         /// <typeparam name="T">The type of data to get.</typeparam>

  114         /// <param name="key">object. The key that uniquely identifies the data to retrieve.</param>

  115         /// <returns>A <typeparamref name="T"/> instance or null if not found.</returns>

  116         public T Get<T>(object key)

  117         {

  118             if (UseLocking)

  119             {

  120                 lock (LockInstance)

  121                     return (T)GetInternalHashtable()[key];

  122             }

  123             return (T)GetInternalHashtable()[key];

  124         }

  125 

  126         /// <summary>

  127         /// Adds or updates the data specified with the key in <see cref="Storage"/>.

  128         /// </summary>

  129         /// <typeparam name="T">The type of data to add or update.</typeparam>

  130         /// <param name="key">object. The key that uniquely identifies the data being stored.</param>

  131         /// <param name="value"><typeparamref name="T"/>. The value to add or update.</param>

  132         public void Set<T>(object key, T value)

  133         {

  134             if (UseLocking)

  135             {

  136                 lock (LockInstance)

  137                     GetInternalHashtable()[key] = value;

  138             }

  139             else

  140                 GetInternalHashtable()[key] = value;

  141         }

  142 

  143         /// <summary>

  144         /// Checks whether the <see cref="AppStorage"/> contains data with the specified key.

  145         /// </summary>

  146         /// <param name="key">object. The unique key to check for.</param>

  147         /// <returns>True if data specified with the key was found, else false.</returns>

  148         public bool Contains(object key)

  149         {

  150             if (UseLocking)

  151             {

  152                 lock (LockInstance)

  153                     return GetInternalHashtable().ContainsKey(key);

  154             }

  155             return GetInternalHashtable().ContainsKey(key);

  156         }

  157 

  158         /// <summary>

  159         /// Removes the data specified with the key in <see cref="Storage"/>.

  160         /// </summary>

  161         /// <param name="key"></param>

  162         /// <returns></returns>

  163         public void Remove(object key)

  164         {

  165             if (UseLocking)

  166             {

  167                 lock (LockInstance)

  168                     GetInternalHashtable().Remove(key);

  169             }

  170             else

  171                 GetInternalHashtable().Remove(key);

  172         }

  173 

  174         /// <summary>

  175         /// Removes all data in <see cref="Storage"/>.

  176         /// </summary>

  177         public void Clear()

  178         {

  179             if (UseLocking)

  180             {

  181                 lock (LockInstance)

  182                     GetInternalHashtable().Clear();

  183             }

  184             else

  185                 GetInternalHashtable().Clear();

  186         }

  187         #endregion

  188 

  189         #region abstract members

  190         /// <summary>

  191         /// When overriden, tells whether the <see cref="Storage"/> uses locking when retrieving and setting values.

  192         /// </summary>

  193         protected abstract bool UseLocking { get; }

  194 

  195         /// <summary>

  196         /// Gets the object used by the <see cref="Storage"/> for locking when retrieving and setting values.

  197         /// </summary>

  198         protected abstract object LockInstance { get; }

  199 

  200         ///<summary>

  201         /// When overriden by a sub class, provides the internal Hashtable used to store and retrieve

  202         /// data.

  203         ///</summary>

  204         ///<returns></returns>

  205         protected abstract Hashtable GetInternalHashtable();

  206         #endregion

  207     }

AppStorage.cs

   22     public class AppStorage : Storage

   23     {

   24         #region fields

   25         private static Hashtable _internalStorage;

   26         #endregion

   27 

   28         #region properties

   29         /// <summary>

   30         /// Overriden. Configures the storage to use locking when getting and setting values.

   31         /// </summary>

   32         protected override bool UseLocking

   33         {

   34             get { return true; }

   35         }

   36 

   37         /// <summary>

   38         /// Gets the object used by the <see cref="Storage"/> for locking when retrieving and setting values.

   39         /// </summary>

   40         protected override object LockInstance

   41         {

   42             get { return AppStorageLock; }

   43         }

   44         #endregion

   45 

   46         #region methods

   47         ///<summary>

   48         /// Overriden. Gets the internal hash table that is used to store and retrieve application

   49         /// specific data.

   50         ///</summary>

   51         ///<returns>A <see cref="Hashtable"/> that is used to store application specific data.</returns>

   52         /// <remarks>

   53         /// This method implementation uses locking as multiple threads (or requests in the case of a web app) can call

   54         /// the GetInternalHashtable at the same time.

   55         /// </remarks>

   56         protected override Hashtable GetInternalHashtable()

   57         {

   58             if (IsWebApplication)

   59             {

   60                 //This code is executing under a WebSite. Use the Application context to retrieve the hash table.

   61                 Hashtable internalHashtable = System.Web.HttpContext.Current.Application[typeof(LocalStorage).FullName] as Hashtable;

   62                 if (internalHashtable == null)

   63                 {

   64                     lock(AppStorageLock)

   65                     {

   66                         internalHashtable = System.Web.HttpContext.Current.Application[typeof(LocalStorage).FullName] as Hashtable;

   67                         if (internalHashtable == null)

   68                             System.Web.HttpContext.Current.Application[typeof(LocalStorage).FullName] = internalHashtable = new Hashtable();   

   69                     }

   70                 }

   71                 return internalHashtable;

   72             }

   73 

   74             //The code is running under a normal windows application. Use the static property.

   75             if (_internalStorage == null)

   76             {

   77                 lock (SessionStorageLock)

   78                 {

   79                     if (_internalStorage == null)

   80                         _internalStorage = new Hashtable();

   81                 }

   82             }

   83             return _internalStorage;

   84         }

   85         #endregion

   86     }

LocalStorage.cs

   23     public class LocalStorage : Storage

   24     {

   25         #region fields

   26         [ThreadStatic]

   27         private static Hashtable _internalStorage;

   28         #endregion

   29 

   30         #region properties

   31         /// <summary>

   32         /// Overriden. Configures the storage to not use locking when getting and setting values.

   33         /// </summary>

   34         protected override bool UseLocking

   35         {

   36             get { return false; }

   37         }

   38 

   39         /// <summary>

   40         /// Gets the object used by the <see cref="Storage"/> for locking when retrieving and setting values.

   41         /// </summary>

   42         protected override object LockInstance

   43         {

   44             get { return null; }

   45         }

   46         #endregion

   47 

   48         #region methods

   49         /// <summary>

   50         /// Overriden. Gets the <see cref="Hashtable"/> used to store thread specific data.

   51         /// </summary>

   52         /// <returns>A <see cref="Hashtable"/> that can be used to store thread / request specific data.</returns>

   53         /// <remarks>

   54         /// No locking is used when initializing the Hashtables as only one request to GetInternalHashtable can be made at one time.

   55         /// This code block is thread-safe

   56         /// </remarks>

   57         protected override Hashtable GetInternalHashtable()

   58         {

   59             if (IsWebApplication)

   60             {

   61                 Hashtable internalStorage = System.Web.HttpContext.Current.Items[typeof(LocalStorage).FullName] as Hashtable;

   62                 if (internalStorage == null)

   63                     System.Web.HttpContext.Current.Items[typeof(LocalStorage).FullName] = internalStorage = new Hashtable();

   64                 return internalStorage;

   65             }

   66             else

   67                 return _internalStorage ?? (_internalStorage = new Hashtable());

   68         }

   69         #endregion

   70     }

SessionStorage.cs

   24     public class SessionStorage : Storage

   25     {

   26         #region properties

   27         /// <summary>

   28         /// Overriden. Configures the storage to use locking when getting and setting values.

   29         /// </summary>

   30         protected override bool UseLocking

   31         {

   32             get { return true; }

   33         }

   34 

   35         /// <summary>

   36         /// Gets the object used by the <see cref="Storage"/> for locking when retrieving and setting values.

   37         /// </summary>

   38         protected override object LockInstance

   39         {

   40             get { return SessionStorageLock; }

   41         }

   42         #endregion

   43 

   44         #region methods

   45         /// <summary>

   46         /// Overriden. Gets the <see cref="Hashtable"/> used to store thread specific data.

   47         /// </summary>

   48         /// <returns>A <see cref="Hashtable"/> that can be used to store Session specific data.</returns>

   49         /// <remarks>

   50         /// This code block uses locking to create the Hashtable as multiple requests can execute under the same session in

   51         /// the case AJAX calls.

   52         /// </remarks>

   53         protected override Hashtable GetInternalHashtable()

   54         {

   55             Guard.Against<InvalidOperationException>(!IsWebApplication || HttpContext.Current.Session == null,

   56                                                     "An ASP.Net session must be available when using Session storage. No ASP.Net session was found in the current context.");

   57 

   58             Hashtable internalStorage = HttpContext.Current.Session[typeof(SessionStorage).FullName] as Hashtable;

   59             if (internalStorage == null)

   60             {

   61                 lock(SessionStorageLock)

   62                 {

   63                     internalStorage = HttpContext.Current.Session[typeof(SessionStorage).FullName] as Hashtable;

   64                     if (internalStorage == null)

   65                         HttpContext.Current.Session[typeof(SessionStorage).FullName] = internalStorage = new Hashtable();

   66                 }

   67             }

   68             return internalStorage;

   69         }

   70         #endregion

   71     }


Building a IoC wrapper component:

Starting with an abstract class, I start out with first defining abstract methods on an abstract IoC class. These abstract methods are the most common IoC methods I use in my applications and largely comprize of resolving component dependencies:

   13     public abstract class IoC

   14     {

   15         /// <summary>

   16         /// When overriden, should initialize and configure the container with the optionally provided

   17         /// path to the configuration file path.

   18         /// </summary>

   19         /// <param name="configFilePath">string. An optional path to the external configuration file

   20         /// that should be used by the container to initialize itself.</param>

   21         protected abstract void Initialize(string configFilePath);

   22 

   23         /// <summary>

   24         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type.

   25         /// </summary>

   26         /// <typeparam name="T">The type of component to resolve or build.</typeparam>

   27         /// <returns>An instance of <typeparamref name="T"/>.</returns>

   28         public abstract T Resolve<T>();

   29 

   30         /// <summary>

   31         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and service name

   32         /// </summary>

   33         /// <typeparam name="T">The type of component to resolve or build.</typeparam>

   34         /// <param name="serviceName">string. The component key that the component is registered with.</param>

   35         /// <returns>An instance of <typeparamref name="T"/>.</returns>

   36         public abstract T Resolve<T>(string serviceName);

   37 

   38         /// <summary>

   39         /// When overriden, tries to resolve a component of the specified <paramref name="type"/>

   40         /// returning a new instance of the type <typeparam name="T"/>

   41         /// </summary>

   42         /// <param name="type">A <see cref="Type"/> instance representing the type to resolve.</param>

   43         /// <returns>object. The resolved component if it exists.</returns>

   44         public abstract T Resolve<T>(Type type);

   45 

   46         /// <summary>

   47         /// When overriden, tries to resolve a component of the specified <paramref name="type"/> and service name

   48         /// returning a new instance of the type <typeparam name="T"/>

   49         /// </summary>

   50         /// <param name="type">A <see cref="Type"/> instance representing the type to resolve.</param>

   51         /// <param name="serviceName">string. The component key that the component is registered with.</param>

   52         /// <returns>object. The resolved component if it exists.</returns>

   53         public abstract T Resolve<T>(Type type, string serviceName);

   54 

   55         /// <summary>

   56         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and

   57         /// returns null (or default value for value types) when the component is not found.

   58         /// </summary>

   59         /// <typeparam name="T">The type of component to resolve.</typeparam>

   60         /// <returns>An instance of <typeparamref name="T"/> or null if the compnent is not found.</returns>

   61         public abstract T TryResolve<T>();

   62 

   63         /// <summary>

   64         /// When overriden, tries to resolve a component of type <typeparam name="T"/> registered for the type

   65         /// <paramref name="type"/> and returns null (or default value for value types) when the component is not found.

   66         /// </summary>

   67         /// <param name="type">The registered component to resolve..</param>

   68         /// <returns>An instance of the component if found, else null.</returns>

   69         public abstract T TryResolve<T>(Type type);

   70 

   71         /// <summary>

   72         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and

   73         /// returns the default value provided when the component is not found.

   74         /// </summary>

   75         /// <typeparam name="T">The type of component to resolve.</typeparam>

   76         /// <param name="defaultValue">An optional default instance of <typeparamref name="T"/> that is

   77         /// returned in case the component could not be resolved.</param>

   78         /// <returns>An instance of <typeparamref name="T"/> type.</returns>

   79         public abstract T TryResolve<T>(T defaultValue);

   80 

   81         /// <summary>

   82         /// When overriden, tries to resolve a component of the specified <typeparam name="T"/> type registered

   83         /// with the <paramref name="type"/> and returns the default value provided when a component registeration

   84         /// is not provided.

   85         /// </summary>

   86         /// <param name="type">The <see cref="Type"/> that the component is registered with.</param>

   87         /// <param name="defaultValue">The default value to return in case the component is not registered.</param>

   88         /// <returns>An instance of <typeparamref name="T"/> type or the default value if the component is not found.</returns>

   89         public abstract T TryResolve<T>(Type type, T defaultValue);

   90 

   91         /// <summary>

   92         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> and

   93         /// service name type returning null (or default value for value types) when the component is not found.

   94         /// </summary>

   95         /// <typeparam name="T">The type of component to resolve.</typeparam>

   96         /// <param name="serviceName">string. The component key with which the component is registered.</param>

   97         /// <returns>An instance of <typeparamref name="T"/> type or null if the component is not found.</returns>

   98         public abstract T TryResolve<T>(string serviceName);

   99 

  100         /// <summary>

  101         /// When overriden, tries to resolve the component of the specified <typeparamref name="T"/> and

  102         /// service name type returning the default value when the component is not found.

  103         /// </summary>

  104         /// <typeparam name="T">The type of component to resolve.</typeparam>

  105         /// <param name="serviceName">string. The component key with which the compinent is registered.</param>

  106         /// <param name="defaultValue">The default value to return if not found.</param>

  107         /// <returns>An instance of <typeparamref name="T"/> instance.</returns>

  108         public abstract T TryResolve<T>(string serviceName, T defaultValue);

  109 

  110         /// <summary>

  111         /// When overriden, tries to resolve the component of the specified <typeparamref name="T"/> registered

  112         /// with the specified <paramref name="type"/> and service name. Returns the default value provided when

  113         /// the registered component is not found.

  114         /// </summary>

  115         /// <typeparam name="T">The type of component to resolve.</typeparam>

  116         /// <param name="type">The <see cref="Type"/> that the component is registered with.</param>

  117         /// <param name="serviceName">string. The component key with which the component is registered.</param>

  118         /// <param name="defaultValue">The default value to return in case the component is not registered.</param>

  119         /// <returns>An instance of <typeparamref name="T"/> type or the default value if the component is not found.</returns>

  120         public abstract T TryResolve<T>(Type type, string serviceName, T defaultValue);

  121     }

The Initialize method is supposed to allow the IoC implementation to initialize and register all components. Next I add a Container property to the IoC class to allow getting an actual implementation of the abstract IoC class:

   33         #region properties

   34         /// <summary>

   35         /// Gets the current IoC container in the current application instance

   36         /// or HttpApplication that used for resolving instances.

   37         /// </summary>

   38         public static IoC Container

   39         {

   40             get

   41             {

   42                 if (Storage.Application.Contains(CONTAINER_KEY))

   43                 {

   44                     lock (typeof(IoC))

   45                     {

   46                         if (!Storage.Application.Contains(CONTAINER_KEY))

   47                         {

   48                             LoadContainer();

   49                         }

   50                     }

   51                 }

   52                 return Storage.Application.Get<IoC>(CONTAINER_KEY);

   53             }

   54         }

   55         #endregion

So the Container property attempts to get the concrete implementation if IoC from the application scope storage, or if it doesn’t exist it then calls a LoadContainer() method to load a default container. I’ll get into LoadContainer() in a moment…

Apart from that, sometimes I would also like to specify the concrete IoC instance to use as the container, mainly for mocking and testing basically. So to allow setting the container I’ve added a SetContainer method:

   60         /// <summary>

   61         /// Sets the container that is used as the current application's <see cref="Container"/> instance.

   62         /// </summary>

   63         /// <param name="instance"></param>

   64         public static void SetContainer(IoC instance)

   65         {

   66             lock (typeof(IoC)) //Sync lock to ensure only one thread updates the application container.

   67             {

   68                 Storage.Application.Set(CONTAINER_KEY, instance);

   69             }

   70         }

So now coming back to LoadContainer. Thinking about how to load up the container that the application use for Dependency Injection, the approach I wanted to take is to allow the application to define the concrete instance using the application’s (or website) configuration file. So what LoadContainer would do is check the configuration to find the Type that should be created as the default IoC container. Of course this Type must inherit from the IoC class. To do this I’ve created a custom configuration section that will be used by the LoadContainer method:

   22     /// <summary>

   23     /// Provides configuration settings to configure and initialize the <see cref="IoC"/> component.

   24     /// </summary>

   25     public class IoCConfiguration : ConfigurationSection

   26     {

   27         /// <summary>

   28         /// Gets or sets the fully qualified type name of a class that inherits from

   29         /// the <see cref="IoC"/> abstract class.

   30         /// </summary>

   31         [ConfigurationProperty("type", DefaultValue = "", IsRequired = true)]

   32         public string Type

   33         {

   34             get { return base["type"] as string;}

   35             set

   36             {

   37                 Guard.Against<NullReferenceException>(string.IsNullOrEmpty(value), "Please specify a valid type that inherits from Vantage.Shared.IoC");

   38                 base["type"] = value;

   39             }

   40         }

   41 

   42         /// <summary>

   43         /// Gets or sets the name of the external file that should be used to initialize

   44         /// the <see cref="IoC"/> implmentation.

   45         /// </summary>

   46         [ConfigurationProperty("fileName", DefaultValue = "", IsRequired = false)]

   47         public string FileName

   48         {

   49             get { return base["fileName"] as string; }

   50             set { base["fileName"] = value; }

   51         }

   52     }

Nothing fancy here, just a simple class inheriting from ConfigurationSection and has two properties; Type that identifies the type of class that should be loaded and an optional FileName to point to an external configuration file that is passed as the filePath parameter of the Initialize method on the IoC class.

With the configuration section defined, here’s the LoadContainer method:

   74         /// <summary>

   75         /// Loads the implementation of IoC container that should be used

   76         /// by the application to resolve instances.

   77         /// </summary>

   78         private static void LoadContainer()

   79         {

   80             //Load the vantage.shared.ioc configuration section for the application.

   81             IoCConfiguration config = ConfigurationManager.GetSection("rhinestone.shared.ioc") as IoCConfiguration;

   82             Guard.Against<ConfigurationException>(config == null, "Configuration section rhinestone.shared.ioc not found. Failed to configure a valid IoC container.");

   83 

   84             //Check and load the IoC implementing type to be used as the IoC container.

   85             Type type = Type.GetType(config.Type);

   86             Guard.InheritsFrom<IoC>(type, "The specified type in rhinestone.shared.ioc does not inherit from Rhinestone.Shared.IoC. Failed to configure valid IoC container.");

   87 

   88             //Creating an instance of the container and setting that instance as the application's container.

   89             IoC container = (IoC) Activator.CreateInstance(type);

   90             container.Initialize(config.FileName);

   91             SetContainer(container);

   92         }

Here’s the full IoC class:

   22 /// <summary>

   23     /// The IoC abstract classes is implemented by IoC container providers

   24     /// that provide inversion of control and service lookup functionality.

   25     /// </summary>

   26     public abstract class IoC

   27     {

   28         #region fields

   29         //Key field used as a key to get the container from the ApplicationData

   30         private static readonly object CONTAINER_KEY = typeof (IoC);

   31         #endregion

   32 

   33         #region properties

   34         /// <summary>

   35         /// Gets the current IoC container in the current application instance

   36         /// or HttpApplication that used for resolving instances.

   37         /// </summary>

   38         public static IoC Container

   39         {

   40             get

   41             {

   42                 if (Storage.Application.Contains(CONTAINER_KEY))

   43                 {

   44                     lock (typeof(IoC))

   45                     {

   46                         if (!Storage.Application.Contains(CONTAINER_KEY))

   47                         {

   48                             LoadContainer();

   49                         }

   50                     }

   51                 }

   52                 return Storage.Application.Get<IoC>(CONTAINER_KEY);

   53             }

   54         }

   55         #endregion

   56 

   57         #region methods

   58 

   59         #region public

   60         /// <summary>

   61         /// Sets the container that is used as the current application's <see cref="Container"/> instance.

   62         /// </summary>

   63         /// <param name="instance"></param>

   64         public static void SetContainer(IoC instance)

   65         {

   66             lock (typeof(IoC)) //Sync lock to ensure only one thread updates the application container.

   67             {

   68                 Storage.Application.Set(CONTAINER_KEY, instance);

   69             }

   70         }

   71         #endregion

   72 

   73         #region private

   74         /// <summary>

   75         /// Loads the implementation of IoC container that should be used

   76         /// by the application to resolve instances.

   77         /// </summary>

   78         private static void LoadContainer()

   79         {

   80             //Load the vantage.shared.ioc configuration section for the application.

   81             IoCConfiguration config = ConfigurationManager.GetSection("rhinestone.shared.ioc") as IoCConfiguration;

   82             Guard.Against<ConfigurationException>(config == null, "Configuration section rhinestone.shared.ioc not found. Failed to configure a valid IoC container.");

   83 

   84             //Check and load the IoC implementing type to be used as the IoC container.

   85             Type type = Type.GetType(config.Type);

   86             Guard.InheritsFrom<IoC>(type, "The specified type in rhinestone.shared.ioc does not inherit from Rhinestone.Shared.IoC. Failed to configure valid IoC container.");

   87 

   88             //Creating an instance of the container and setting that instance as the application's container.

   89             IoC container = (IoC) Activator.CreateInstance(type);

   90             container.Initialize(config.FileName);

   91             SetContainer(container);

   92         }

   93         #endregion

   94 

   95         #region abstract

   96         /// <summary>

   97         /// When overriden, should initialize and configure the container with the optionally provided

   98         /// path to the configuration file path.

   99         /// </summary>

  100         /// <param name="configFilePath">string. An optional path to the external configuration file

  101         /// that should be used by the container to initialize itself.</param>

  102         protected abstract void Initialize(string configFilePath);

  103 

  104         /// <summary>

  105         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type.

  106         /// </summary>

  107         /// <typeparam name="T">The type of component to resolve or build.</typeparam>

  108         /// <returns>An instance of <typeparamref name="T"/>.</returns>

  109         public abstract T Resolve<T>();

  110 

  111         /// <summary>

  112         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and service name

  113         /// </summary>

  114         /// <typeparam name="T">The type of component to resolve or build.</typeparam>

  115         /// <param name="serviceName">string. The component key that the component is registered with.</param>

  116         /// <returns>An instance of <typeparamref name="T"/>.</returns>

  117         public abstract T Resolve<T>(string serviceName);

  118 

  119         /// <summary>

  120         /// When overriden, tries to resolve a component of the specified <paramref name="type"/>

  121         /// returning a new instance of the type <typeparam name="T"/>

  122         /// </summary>

  123         /// <param name="type">A <see cref="Type"/> instance representing the type to resolve.</param>

  124         /// <returns>object. The resolved component if it exists.</returns>

  125         public abstract T Resolve<T>(Type type);

  126 

  127         /// <summary>

  128         /// When overriden, tries to resolve a component of the specified <paramref name="type"/> and service name

  129         /// returning a new instance of the type <typeparam name="T"/>

  130         /// </summary>

  131         /// <param name="type">A <see cref="Type"/> instance representing the type to resolve.</param>

  132         /// <param name="serviceName">string. The component key that the component is registered with.</param>

  133         /// <returns>object. The resolved component if it exists.</returns>

  134         public abstract T Resolve<T>(Type type, string serviceName);

  135 

  136         /// <summary>

  137         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and

  138         /// returns null (or default value for value types) when the component is not found.

  139         /// </summary>

  140         /// <typeparam name="T">The type of component to resolve.</typeparam>

  141         /// <returns>An instance of <typeparamref name="T"/> or null if the compnent is not found.</returns>

  142         public abstract T TryResolve<T>();

  143 

  144         /// <summary>

  145         /// When overriden, tries to resolve a component of type <typeparam name="T"/> registered for the type

  146         /// <paramref name="type"/> and returns null (or default value for value types) when the component is not found.

  147         /// </summary>

  148         /// <param name="type">The registered component to resolve..</param>

  149         /// <returns>An instance of the component if found, else null.</returns>

  150         public abstract T TryResolve<T>(Type type);

  151 

  152         /// <summary>

  153         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> type and

  154         /// returns the default value provided when the component is not found.

  155         /// </summary>

  156         /// <typeparam name="T">The type of component to resolve.</typeparam>

  157         /// <param name="defaultValue">An optional default instance of <typeparamref name="T"/> that is

  158         /// returned in case the component could not be resolved.</param>

  159         /// <returns>An instance of <typeparamref name="T"/> type.</returns>

  160         public abstract T TryResolve<T>(T defaultValue);

  161 

  162         /// <summary>

  163         /// When overriden, tries to resolve a component of the specified <typeparam name="T"/> type registered

  164         /// with the <paramref name="type"/> and returns the default value provided when a component registeration

  165         /// is not provided.

  166         /// </summary>

  167         /// <param name="type">The <see cref="Type"/> that the component is registered with.</param>

  168         /// <param name="defaultValue">The default value to return in case the component is not registered.</param>

  169         /// <returns>An instance of <typeparamref name="T"/> type or the default value if the component is not found.</returns>

  170         public abstract T TryResolve<T>(Type type, T defaultValue);

  171 

  172         /// <summary>

  173         /// When overriden, tries to resolve a component of the specified <typeparamref name="T"/> and

  174         /// service name type returning null (or default value for value types) when the component is not found.

  175         /// </summary>

  176         /// <typeparam name="T">The type of component to resolve.</typeparam>

  177         /// <param name="serviceName">string. The component key with which the component is registered.</param>

  178         /// <returns>An instance of <typeparamref name="T"/> type or null if the component is not found.</returns>

  179         public abstract T TryResolve<T>(string serviceName);

  180 

  181         /// <summary>

  182         /// When overriden, tries to resolve the component of the specified <typeparamref name="T"/> and

  183         /// service name type returning the default value when the component is not found.

  184         /// </summary>

  185         /// <typeparam name="T">The type of component to resolve.</typeparam>

  186         /// <param name="serviceName">string. The component key with which the compinent is registered.</param>

  187         /// <param name="defaultValue">The default value to return if not found.</param>

  188         /// <returns>An instance of <typeparamref name="T"/> instance.</returns>

  189         public abstract T TryResolve<T>(string serviceName,T defaultValue);

  190 

  191         /// <summary>

  192         /// When overriden, tries to resolve the component of the specified <typeparamref name="T"/> registered

  193         /// with the specified <paramref name="type"/> and service name. Returns the default value provided when

  194         /// the registered component is not found.

  195         /// </summary>

  196         /// <typeparam name="T">The type of component to resolve.</typeparam>

  197         /// <param name="type">The <see cref="Type"/> that the component is registered with.</param>

  198         /// <param name="serviceName">string. The component key with which the component is registered.</param>

  199         /// <param name="defaultValue">The default value to return in case the component is not registered.</param>

  200         /// <returns>An instance of <typeparamref name="T"/> type or the default value if the component is not found.</returns>

  201         public abstract T TryResolve<T>(Type type, string serviceName, T defaultValue);

  202         #endregion

  203 

  204         #endregion

Providing an implementation for StructureMap:

Okay, so now that I have a IoC wrapper how would one use you might ask? So for you application or website or whatever… you could then create a subclass of IoC, set it up in the Initialize methods and then delegate the Resolve calls to the actual container of your choice. Here is one example using StructureMap, the following class can be used as a generic StructureMap container:

   15     public class StructureMapContainer : IoC

   16     {

   17         #region Overrides of IoC

   18         protected override void Initialize(string configFilePath)

   19         {

   20             //Initialize the object factory and setup the

   21             if (string.IsNullOrEmpty(configFilePath))

   22                 StructureMapConfiguration.ScanAssemblies();

   23             else

   24                 StructureMapConfiguration.IncludeConfigurationFromFile(configFilePath);

   25         }

   26 

   27         public override T Resolve<T>()

   28         {

   29             return ObjectFactory.GetInstance<T>();

   30         }

   31 

   32         public override T Resolve<T>(string serviceName)

   33         {

   34             return ObjectFactory.GetNamedInstance<T>(serviceName);

   35         }

   36 

   37         public override T Resolve<T>(Type type)

   38         {

   39             return (T) ObjectFactory.GetInstance(type);

   40         }

   41 

   42         public override T Resolve<T>(Type type, string serviceName)

   43         {

   44             return (T) ObjectFactory.GetNamedInstance(type, serviceName);

   45         }

   46 

   47         public override T TryResolve<T>()

   48         {

   49             return TryResolve(default(T));

   50         }

   51 

   52         public override T TryResolve<T>(Type type)

   53         {

   54             return TryResolve(type, default(T));

   55         }

   56 

   57         public override T TryResolve<T>(T defaultValue)

   58         {

   59             try

   60             {

   61                 object instance = ObjectFactory.GetInstance<T>();

   62                 return instance == null ? defaultValue : (T)instance;

   63             }

   64             catch (Exception)

   65             {

   66                 return defaultValue;

   67             }

   68         }

   69 

   70         public override T TryResolve<T>(Type type, T defaultValue)

   71         {

   72             try

   73             {

   74                 object instance = ObjectFactory.GetInstance(type);

   75                 return instance == null ? defaultValue : (T)instance;

   76             }

   77             catch (Exception)

   78             {

   79                 return defaultValue;

   80             }

   81         }

   82 

   83         public override T TryResolve<T>(string serviceName)

   84         {

   85             return TryResolve(serviceName, default(T));

   86         }

   87 

   88         public override T TryResolve<T>(string serviceName, T defaultValue)

   89         {

   90             try

   91             {

   92                 object instance = ObjectFactory.GetNamedInstance<T>(serviceName);

   93                 return instance == null ? defaultValue : (T)instance;

   94             }

   95             catch (Exception)

   96             {

   97                 return defaultValue;

   98             };

   99         }

  100 

  101         public override T TryResolve<T>(Type type, string serviceName, T defaultValue)

  102         {

  103             try

  104             {

  105                 object instance = ObjectFactory.GetNamedInstance(type, serviceName);

  106                 return instance == null ? defaultValue : (T)instance;

  107             }

  108             catch (Exception)

  109             {

  110                 return defaultValue;

  111             };

  112         }

  113         #endregion

  114     }

Using the StructureMapContainer now, I can either use a configuration file to define the registered plugin types or use the Registry class and define component registrations using that. But the bottom line is that my application isn’t really tied down to one implementation of an IoC container and I can swap out implementations quite easily since my application uses the IoC wrapper.

The complete source for the IoC wrapper can be found in Rhinestone’s source code: https://rhinestone.googlecode.com/svn/trunk/src/Rhinestone.Shared/IoC


[Edit: Fixed the url to the source code.

In my previous post, Implementing Repository and Specification patterns using Linq, I implemented a Repository pattern that allows consumers of the repository to use Linq to query the repository. Along with implementing a Repository pattern I also implemented a pattern for defining Specifications that could be used by not only Domain objects but also can be used with the Repository implementation for querying.

In response to that post, there were a number of comments regarding how the RepositoryBase could be used to implement a Repository for Linq to SQL and also questions surrounding persistence and unit of work pattern. In this post I set out to create a sample project that uses the RepositoryBase for implementing the repository pattern using Domain Driven Design. The sample with also demonstrate how Persistence Ignorance can be achieved using the RepositoryBase. In the sample I will show how you can easily switch the persistence layer between Linq to SQL and NHibernate. (I won’t go into Entity Framework in this post because that’s a whole different can of worms.)

Before I go ahead and start with the sample a note first; the Unit Of Work implementation provided in this sample is a not a solid implementation that should not be considered as guidance or the right way to implement the pattern. If you would like more information on the Unit Of Work pattern please see the reference links at the end of this post. I will not be going into detail on the Unit of Work pattern in this post as that requires a whole new post.

With that out of the way, lets start implementing the sample. The sample application that I will implement in this post will be on the lines of a classic Customer Ordering application. So we have a customer which can make orders which in turn has order lines containing details of the quantuty, price and Product that the customer has ordered.

The Domain Model:

Below is the Domain Model of the Sample application:

Model

The Model is fairly vanilla, where we have a Customer domain entity, that holds a list of Order instances. The Order domain entity holds instances of OrderDetail entities that reference a Product entity. Based on the dommain, the Customer and Order would be the Aggregate Roots.

Building a base for Unit Of Work:

Okay, so the first thing is to layout a foundation for the Unit of Work pattern. The Unit of Work pattern provides a way to keep a track of all changes you make as a single unit and persists all those changes to the data store as a single unit. What the Unit Of Work allows is making changes to the data store as a single unit, avoiding individual updates to the data store which lets to multiple trips to the data store.

As always, I start with an interface;

    5     public interface IUnitOfWork : IDisposable

    6     {

    7         void BeginTransaction();

    8         void CommitTransaction();

    9         void RollbackTransaction();

   10     }

So here I have defined a IUnitOfWork interface that provides has three methods that deal with managing transactions. To provide concrete implementations of IUnitOfWork there is a UnitOfWork class that has two methods on it, Start and Finish.

    5     public static class UnitOfWork

    6     {

    7         #region fields

    8         private static IUnitOfWork _currentUnitOfWork;

    9         #endregion

   10 

   11         #region properties

   12         public static IUnitOfWork Current

   13         {

   14             get { return _currentUnitOfWork; }

   15         }

   16         #endregion

   17 

   18         #region methods

   19         public static IUnitOfWork Start ()

   20         {

   21             if (_currentUnitOfWork != null)

   22                 return _currentUnitOfWork;

   23             return _currentUnitOfWork = IoC.Container.Resolve<IUnitOfWork>();

   24         }

   25 

   26         public static void Finish (bool commit)

   27         {

   28             if (_currentUnitOfWork == null)

   29                 throw new InvalidOperationException();

   30             if (commit)

   31                 _currentUnitOfWork.CommitTransaction();

   32             _currentUnitOfWork.Dispose();

   33             _currentUnitOfWork = null;

   34         }

   35         #endregion

   36     }

So to start a Unit of Work, we can call the Start method on the UnitOfWork which gets a concrete implementation of IUnitOfWork from a IoC container. Once we are done we can call the Finish method.

Note: This is probably the least desirable way to implement the UnitOfWork pattern, but this is done in this sample to provide the simplest way of starting and finishing a unit of work.

Implementing the IUnitOfWork and RepositoryBase for Linq to SQL:

When starting to implement a repository that uses Linq To SQL, I chose to define a external XML mapping file to define the Linq to SQL mapping instead of using the Linq to SQL designer. This allows me to keep my domain objects free from having infrastructure concerns and not being tied to Linq To SQL allowing me to replace Linq to SQL with NHibernate. But using a mapping file to define the Linq to SQL mapping also has it’s downside. First is that we cannot take advantage of the lazy loading functionality that Linq to SQL provides. This is because Linq To SQL expects lazy loaded objects and collections be defined as EntityRef<T> and EntitySet<T> types. I could define the associations in the domain model as EntityRef<T> and EntitySet<T> but that would introduce infrastructure concerns into the domain thus making it difficult for me to replace Linq to SQL with NHibernate later on.

So I have decided to skip on lazy loading for now. Defining a mapping file for Linq to SQL is pretty easy and straight forwarding and you could always use SqlMetal to get a Xml mapping file generated from your database. Below is the complete mapping file:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <Database xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007" Name="LinqRepositorySampleDB">

    3   <Table Name="dbo.Customers" Member="Customers">

    4     <Type Name="LinqRepositorySample.Domain.Customer">

    5       <Column Name="CustomerID" Member="CustomerId" DbType="Int NOT NULL IDENTITY"

    6               Storage="_customerId" IsPrimaryKey="true" IsDbGenerated="true"/>

    7       <Column Name="FirstName" Member="FirstName" DbType="VarChar(200) NOT NULL"/>

    8       <Column Name="LastName" Member="LastName" DbType="VarChar(200) NOT NULL"/>

    9       <Column Name="StreetAddress1" Member="StreetAddress1" DbType="VarChar(500) NOT NULL"/>

   10       <Column Name="StreetAddress2" Member="StreetAddress2" DbType="VarChar(500) NULL"/>

   11       <Column Name="City" Member="City" DbType="VarChar(100) NOT NULL"/>

   12       <Column Name="State" Member="State" DbType="Char(2) NOT NULL"/>

   13       <Column Name="ZipCode" Member="ZipCode" DbType="VarChar(5) NOT NULL"/>

   14       <Association Name="Customer_Orders" Member="Orders" Storage="_orders"

   15                   ThisKey="CustomerId" OtherKey="CustomerId"/>

   16     </Type>

   17   </Table>

   18   <Table Name="dbo.Products" Member="Products">

   19     <Type Name="LinqRepositorySample.Domain.Product">

   20       <Column Name="ProductID" Member="ProductId" Storage="_productId" DbType="Int NOT NULL IDENTITY"

   21               IsPrimaryKey="true" IsDbGenerated="true"/>

   22       <Column Name="ProductName" Member="Name" DbType="VarChar(200) NOT NULL"/>

   23       <Column Name="ProductCategory" Member="Category" DbType="VarChar(50) NOT NULL"/>

   24       <Column Name="StandardCost" Member="StandardCost" DbType="Money NOT NULL"/>

   25       <Column Name="StandardPrice" Member="StandardPrice" DbType="Money NOT NULL"/>

   26     </Type>

   27   </Table>

   28   <Table Name="dbo.Orders" Member="Orders">

   29     <Type Name="LinqRepositorySample.Domain.Order">

   30       <Column Name="OrderID" Member="OrderId" Storage="_orderId"

   31               DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true"/>

   32       <Column Name="CustomerID" Member="CustomerId" CanBeNull="true"/>

   33       <Association Name="Order_Customer" Member="Customer" Storage="_customer"

   34                   ThisKey="CustomerId" OtherKey="CustomerId" IsForeignKey="true" />

   35       <Column Name="OrderDate" Member="OrderDate" DbType="DateTime NOT NULL"/>

   36       <Column Name="ScheduledDeliveryDate" Member="ScheduledDelivery" DbType="DateTime NOT NULL"/>

   37       <Column Name="Delivered" Member="Delivered" DbType="Bit NOT NULL"/>

   38       <Association Name="Order_OrderDetails" Member="OrderDetails" Storage="_orderDetails"

   39                   ThisKey="OrderId" OtherKey="OrderId" />

   40     </Type>

   41   </Table>

   42   <Table Name="dbo.OrderDetails" Member="OrderDetails">

   43     <Type Name="LinqRepositorySample.Domain.OrderDetail">

   44       <Column Name="OrderLineID" Member="OrderDetailId" Storage="_orderDetailId"

   45               DbType="Int IDENTITY NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" />

   46       <Column Name="ProductID" Member="ProductId"/>

   47       <Column Name="OrderID" Member="OrderId" CanBeNull="true"/>

   48       <Column Name="Total" Member="Total"/>

   49       <Association Name="OrderDetail_Order" Member="Order" Storage="_order"

   50                   ThisKey="OrderId" OtherKey="OrderId" IsForeignKey="true" />

   51       <Association Name="OrderDetail_Product" Member="Product" ThisKey="ProductId"

   52                   OtherKey="ProductId" IsForeignKey="true" />

   53       <Column Name="Qty" Member="Qty" DbType="Int NOT NULL"/>

   54       <Column Name="Price" Member="Price" DbType="Money NOT NULL"/>

   55     </Type>

   56   </Table>

   57 </Database>

The next step is to provide an implementation of IUnitOfWork that creates a DataContext that consumes the above mapping file. Here it is:

    1 using System;

    2 using System.Configuration;

    3 using System.Data;

    4 using System.Data.Common;

    5 using System.Data.Linq;

    6 using System.Data.Linq.Mapping;

    7 using System.IO;

    8 using LinqRepositorySample.Domain;

    9 

   10 namespace LinqRepositorySample.Data.LinqToSql

   11 {

   12     public class LinqUnitOfWork : IUnitOfWork

   13     {

   14         #region fields

   15         private DataContext _currentContext;

   16         private DbTransaction _currentTransaction;

   17         private bool _disposed;

   18         #endregion

   19 

   20         #region .ctor

   21         public LinqUnitOfWork ()

   22         {

   23             CreateDataContext();

   24         }

   25 

   26         private void CreateDataContext() {

   27             Stream mappings = GetType().Assembly.GetManifestResourceStream("LinqRepositorySample.Data.LinqToSql.mapping.xml");

   28             XmlMappingSource mappingSource = XmlMappingSource.FromStream(mappings);

   29             _currentContext = new DataContext(ConfigurationManager.ConnectionStrings["SampleDB"].ConnectionString,

   30                                               mappingSource);

   31             _currentContext.DeferredLoadingEnabled = false;

   32             DataLoadOptions loadOptions = new DataLoadOptions();

   33             loadOptions.LoadWith<Customer>(x => x.Orders);

   34             loadOptions.LoadWith<Order>(x => x.OrderDetails);

   35             loadOptions.LoadWith<OrderDetail>(x => x.Product);

   36             _currentContext.LoadOptions = loadOptions;

   37         }

   38         #endregion

   39 

   40         #region properties

   41         public DataContext Context

   42         {

   43             get { return _currentContext; }

   44         }

   45         #endregion

   46 

   47         #region Implementation of IDisposable

   48         public void Dispose()

   49         {

   50             if (!_disposed)

   51             {

   52                 Dispose(true);

   53                 GC.SuppressFinalize(this);

   54                 _disposed = true;

   55             }

   56         }

   57 

   58         private void Dispose(bool disposing)

   59         {

   60             if (disposing)

   61             {

   62                 if (_currentTransaction != null)

   63                 {

   64                     _currentTransaction.Dispose();

   65                     _currentTransaction = null;

   66                 }

   67                 if (_currentContext != null)

   68                 {

   69                     _currentContext.Dispose();

   70                     _currentContext = null;

   71                 }

   72             }

   73         }

   74         #endregion

   75 

   76         #region Implementation of IUnitOfWork

   77         public void BeginTransaction()

   78         {

   79             //Ignore: The DataContext uses an implicit transaction and makes all changes made to the data context within one transaction.

   80         }

   81 

   82         public void CommitTransaction()

   83         {

   84             _currentContext.SubmitChanges();

   85         }

   86 

   87         public void RollbackTransaction()

   88         {

   89             CreateDataContext(); //Discarding changes by creating a new data context... probably the most dummest requirement of Linq to SQL

   90         }

   91         #endregion

   92     }

   93 }

So what we have here is a LinqUnitOfWork class that implements the IUnitOfWork interface that creates a new DataContext instance that uses the mapping file that is embedded into the assembly. The other thing to note is that the LinqUnitOfWork is using DataLoadOptions.LoadWith to specify to use eager loading as our domain entities don’t use EntityRef<T> and EntitySet<T> to define associations. The implemenetation of BeginTransaction also does nothing as the DataContext internally wraps all changes made to the data context within a single transaction when calling SubmitChanges(). Also since there is no real way to discard changes made to the DataContext, which in my opinion is just plain WRONG, the only viable way to discard changes is to scrap the old DataContext and create a new one (stupid… stupid… stupid).

The LinqUnitOfWork class also exposes the DataContext contained by the unit of work instances through the Context property.

The next step is to provide an implementation of RepositoryBase that can be used to query using Linq To SQL using the LinqUnitOfWork implementaiton:

    1 using System;

    2 using System.Data.Linq;

    3 using System.Linq;

    4 using LinqRepositorySample.Domain;

    5 

    6 namespace LinqRepositorySample.Data.LinqToSql

    7 {

    8     public class LinqRepository<T> : RepositoryBase<T> where T : class

    9     {

   10 

   11         #region fields

   12         private Table<T> _table;

   13         #endregion

   14 

   15         #region .ctor

   16         public LinqRepository()

   17         {

   18             if (UnitOfWork.Current == null)

   19                 throw new InvalidOperationException();

   20             LinqUnitOfWork uow = UnitOfWork.Current as LinqUnitOfWork;

   21             if (uow == null)

   22                 throw new InvalidOperationException();

   23             _table = uow.Context.GetTable<T>();

   24         }

   25         #endregion

   26 

   27         #region Overrides of RepositoryBase<T>

   28         /// <summary>

   29         /// Gets the <see cref="IQueryable{T}"/> used by the <see cref="RepositoryBase{T}"/>

   30         /// to execute Linq queries.

   31         /// </summary>

   32         /// <value>A <see cref="IQueryable{T}"/> instance.</value>

   33         /// <remarks>

   34         /// Inheritos of this base class should return a valid non-null <see cref="IQueryable{T}"/> instance.

   35         /// </remarks>

   36         protected override IQueryable<T> RepositoryQuery

   37         {

   38             get { return _table.AsQueryable(); }

   39         }

   40 

   41         /// <summary>

   42         /// Marks the entity instance to be saved to the store.

   43         /// </summary>

   44         /// <param name="entity">An instance of <typeparamref name="T"/> that should be saved

   45         /// to the database.</param>

   46         /// <remarks>Implementors of this method must handle both Insert and Update scenarios.</remarks>

   47         public override void Save(T entity)

   48         {

   49             if (entity == null)

   50                 throw new ArgumentNullException();

   51             _table.InsertOnSubmit(entity);

   52         }

   53 

   54         /// <summary>

   55         /// Marks the entity instance to be deleted from the store.

   56         /// </summary>

   57         /// <param name="entity">An instance of <typeparamref name="T"/> that should be deleted.</param>

   58         public override void Delete(T entity)

   59         {

   60             if (entity == null)

   61                 throw new ArgumentNullException();

   62             _table.DeleteOnSubmit(entity);

   63         }

   64         #endregion

   65     }

   66 }

The above code defines a LinqRepository that checks if a UnitOfWork has been started. If so it tries to cast the current unit of work, provided by UnitOfWork.Current, to a LinqUnitOfWork instance. It then uses the Context property to get the DataContext and gets a Table<T> for the generic type and stores it into the _table field which is then used to get an IQueryable by calling _table.ToQueryable() in the RepositoryQuery poperty.

Providing an Unit of Work and Repository implementation for NHibernate:

So to demonstrate persistence ignorance I’m going to implement IUnitOfWork and RepositoryBase for NHibernate. If you have no experience with NHibernate you can see the reference links at the bottom of this post for links on learning about NHibernate or you can skip this section. I will be posting detailed tutorials on NHibernate soon as well.

Just like Linq to SQL, we start with the mapping files for NHibernate. Below is a sample mapping file for the Order entity:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

    3                     assembly="LinqRepositorySample.Domain"

    4                   namespace="LinqRepositorySample.Domain" schema="dbo">

    5   <class name="Order" table="Orders">

    6     <id name="OrderId" column="OrderID" access="nosetter.camelcase-underscore">

    7       <generator class="identity"/>

    8     </id>

    9     <property name="OrderDate" column="OrderDate"/>

   10     <property name="ScheduledDelivery" column="ScheduledDeliveryDate"/>

   11     <property name="Delivered" column="Delivered"/>

   12     <many-to-one name="Customer" access="nosetter.camelcase-underscore"

   13                 column="CustomerID" class="Customer"/>

   14     <bag name="OrderDetails" table="OrderDetails" access="nosetter.camelcase-underscore" inverse="true" cascade="all-delete-orphan">

   15       <key column="OrderID" foreign-key="OrderID"/>

   16       <one-to-many class="OrderDetail"/>

   17     </bag>

   18   </class>

   19 </hibernate-mapping>

The mappings are simple enough since there aren’t any complex associations or relationships in the domain. So once I have the mappings in place for my domain entities, just like for Linq To SQL the next step is to provide an implementation of IUnitOfWork that uses NHibernate. But before I can do that I need a way to create and get an instance of the ISessionFactory that is responsible for creating sessions. In order to do that I have created a static SessionFactory class:

    1 using NHibernate;

    2 using NHibernate.Cfg;

    3 

    4 namespace LinqRepositorySample.Data.NHibernate

    5 {

    6     public class SessionFactory

    7     {

    8         #region fields

    9         public static readonly ISessionFactory Current;

   10         #endregion

   11 

   12         #region ..ctor

   13         static SessionFactory()

   14         {

   15             Current = new Configuration()

   16                             .Configure()

   17                             .AddAssembly(typeof (SessionFactory).Assembly)

   18                             .BuildSessionFactory();

   19         }

   20         #endregion

   21     }

   22 }

The SessionFactory builds a new instance of the ISessionFactory and stores it in a static readonly field called Current. This way my implementation of IUnitOfWork will be able to build ISession instances without having create ISessionFactory instances for each unit of work, which is bad anyways. Again a reminder, the Unit of Work implementation in this sample is not recommended practice or guidance. In fact I would recommend not using the implementation in this sample AT ALL!!

Okay, so below is the implementation of IUnitOfWork for NHibernate:

    1 using System;

    2 using LinqRepositorySample.Domain;

    3 using NHibernate;

    4 

    5 namespace LinqRepositorySample.Data.NHibernate

    6 {

    7     public class NHibernateUnitOfWork : IUnitOfWork

    8     {

    9         #region fields

   10         private ISession _currentSession;

   11         private ITransaction _currentTransaction;

   12         private bool _disposed;

   13         #endregion

   14 

   15         #region .ctor

   16         public NHibernateUnitOfWork()

   17         {

   18             _currentSession = SessionFactory.Current.OpenSession();

   19         }

   20         #endregion

   21 

   22         #region properties

   23         internal ISession Session

   24         {

   25             get { return _currentSession; }

   26         }

   27         #endregion

   28 

   29         #region Implementation of IDisposable

   30         public void Dispose()

   31         {

   32             if (!_disposed)

   33             {

   34                 Dispose(true);

   35                 GC.SuppressFinalize(this);

   36                 _disposed = true;

   37             }

   38         }

   39 

   40         private void Dispose(bool disposing)

   41         {

   42             if (disposing)

   43             {

   44                 if (_currentTransaction != null)

   45                     _currentTransaction.Dispose();

   46                 if (_currentSession != null)

   47                     _currentSession.Dispose();

   48                 _currentTransaction = null;

   49                 _currentSession = null;

   50             }

   51         }

   52         #endregion

   53 

   54         #region Implementation of IUnitOfWork

   55         public void BeginTransaction()

   56         {

   57             _currentTransaction = _currentSession.BeginTransaction();

   58         }

   59 

   60         public void CommitTransaction()

   61         {

   62             if (_currentTransaction != null)

   63                 _currentTransaction.Commit();

   64         }

   65 

   66         public void RollbackTransaction()

   67         {

   68             if (_currentTransaction != null)

   69                 _currentTransaction.Rollback();

   70         }

   71         #endregion

   72     }

   73 }

Nothing fancy there, I simply get a new ISession from the SessionFactory static class and store it in the _currentSession private variable and expose that as a read-only property Session.

Next is inheriting from RepositoryBase for a NHibernate repository that uses the NHibernateUnitOfWork:

    1 using System;

    2 using System.Linq;

    3 using LinqRepositorySample.Domain;

    4 using NHibernate.Linq;

    5 

    6 namespace LinqRepositorySample.Data.NHibernate

    7 {

    8     public class NHibernateRepository<T> : RepositoryBase<T>

    9     {

   10         #region fields

   11         private IQueryable<T> _query;

   12         #endregion

   13 

   14         #region .ctor

   15         public NHibernateRepository()

   16         {

   17             if (UnitOfWork.Current == null)

   18                 throw new ArgumentNullException();

   19             NHibernateUnitOfWork uow = UnitOfWork.Current as NHibernateUnitOfWork;

   20             if(uow == null)

   21                 throw new ArgumentNullException();

   22             _query = uow.Session.Linq<T>();

   23         }

   24         #endregion

   25 

   26         #region Overrides of RepositoryBase<T>

   27         /// <summary>

   28         /// Gets the <see cref="IQueryable{T}"/> used by the <see cref="RepositoryBase{T}"/>

   29         /// to execute Linq queries.

   30         /// </summary>

   31         /// <value>A <see cref="IQueryable{T}"/> instance.</value>

   32         /// <remarks>

   33         /// Inheritos of this base class should return a valid non-null <see cref="IQueryable{T}"/> instance.

   34         /// </remarks>

   35         protected override IQueryable<T> RepositoryQuery

   36         {

   37             get { return _query; }

   38         }

   39 

   40         /// <summary>

   41         /// Marks the entity instance to be saved to the store.

   42         /// </summary>

   43         /// <param name="entity">An instance of <typeparamref name="T"/> that should be saved

   44         /// to the database.</param>

   45         /// <remarks>Implementors of this method must handle both Insert and Update scenarios.</remarks>

   46         public override void Save(T entity)

   47         {

   48             if (entity == null)

   49                 throw new ArgumentNullException();

   50             ((NHibernateUnitOfWork) UnitOfWork.Current).Session.SaveOrUpdate(entity);

   51         }

   52 

   53         /// <summary>

   54         /// Marks the entity instance to be deleted from the store.

   55         /// </summary>

   56         /// <param name="entity">An instance of <typeparamref name="T"/> that should be deleted.</param>

   57         public override void Delete(T entity)

   58         {

   59             if (entity == null)

   60                 throw new ArgumentNullException();

   61             ((NHibernateUnitOfWork)UnitOfWork.Current).Session.Delete(entity);

   62         }

   63         #endregion

   64     }

   65 }

The NHibernateRepository simpley gets the current NHibernateUnitOfWork and then use NHibernate.Linq to get a IQuerable<T> for the specified type from the current session. One note here is that the NHibernate.Linq (inlcuded in the sample under libs) is still under development and has some rough edges. Overall it does it’s job well enough but I wouldn’t recommend using it in production unless it is for simple apps, at least for a while until all kinks have been worked out.

So now I have implementations of IUnitOfWork and RepositoryBase for both Linq To SQL and NHibernate. Lets see if I can make this monkey do tricks…

Using Castle Windsor to switch between Linq to SQL and NHibernate:

So before I sit down writing tests to see if this thing even works, the first thing that needs doing is a way to be able to switch between Linq to SQL implementations and NHibernate implementation. I’m going to use Castle Windsor for that…

Just like I said I am not going into the UnitOfWork pattern in this post, I’m not going to touch IoC and Dependency Injection either. This post is long enough without cramming two more patterns in it. If you’d like to know more about IoC and DI please see the reference links at the end of this post, or look out for future posts on this blog that will go deep into IoC and DI along with Unit of Work.

Ok, now using Windsor is simple enough, I just need to add the necessary configuration entries to specify the components (Note: I know I’m using Windsor here more like a Service Locator than a Dependency Injector, it’s intentional)

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <configuration>

    3   <configSections>

    4     <section

    5         name="castle"

    6         type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />

    7   </configSections>

    8 

    9   <connectionStrings>

   10     <add name="SampleDB" connectionString="Server=(local);Database=LinqRepositorySampleDB;Integrated Security=SSPI;"/>

   11   </connectionStrings>

   12   <castle>

   13     <components>

   14       <component id="linqunitofwork"

   15                 service="LinqRepositorySample.Domain.IUnitOfWork, LinqRepositorySample.Domain"

   16                 type="LinqRepositorySample.Data.LinqToSql.LinqUnitOfWork, LinqRepositorySample.Data.LinqToSql"

   17                 lifestyle="transient"/>

   18       <component id="linqrepository"

   19                 service="LinqRepositorySample.Domain.IRepository`1, LinqRepositorySample.Domain"

   20                 type="LinqRepositorySample.Data.LinqToSql.LinqRepository`1, LinqRepositorySample.Data.LinqToSql"

   21                 lifestyle="transient"/>

   22 

   23       <!--<component id="nhunitofwork"

   24               service="LinqRepositorySample.Domain.IUnitOfWork, LinqRepositorySample.Domain"

   25               type="LinqRepositorySample.Data.NHibernate.NHibernateUnitOfWork, LinqRepositorySample.Data.NHibernate"

   26               lifestyle="transient"/>

   27       <component id="nhrepository"

   28                 service="LinqRepositorySample.Domain.IRepository`1, LinqRepositorySample.Domain"

   29                 type="LinqRepositorySample.Data.NHibernate.NHibernateRepository`1, LinqRepositorySample.Data.NHibernate"

   30                 lifestyle="transient"/>-->

   31     </components>

   32   </castle>

   33 </configuration>

   34 

   35 

Notice the commented out entries. Those entries are for NHibernate implementations of IUnitOfWork and IRepository. So when you want to run the tests for NHibernate, simply comment the component registrations for Linq to SQL and un-comment the ones for Nhibernate. The components are registered as with transient lifestyle because I want to get new instances of IUnitOfWork and IRepository everytime I request one. Also note the component registration for the IRepository, the returned type is a generic type based on the requested generic type. What that means is that if I request a IRepository<Product> from Windsor, it will return a LinqRepository<Product> or NHibernateRepository<Product>, based on the registered component. That frees me from implementing a Repository for each possible type.

Does this thing work? Time for tests!

Finally, on to some tests. The test I am going to include in the sample are very basic and definitely do not test every aspect of the domain. You are free to add your own tests to the sample to see if the implementation works as per your requirement. So the first set of tests I want to do is querying… can I query the repository using Linq? Below are the tests:

   11         [Test]

   12         public void Select_All_Products()

   13         {

   14             UnitOfWork.Start();

   15             IRepository<Product> productsRepository = IoC.Container.Resolve<IRepository<Product>>();

   16             var results = from product in productsRepository

   17                           select product;

   18 

   19             Assert.That(results.Count() > 0);

   20             Assert.That(results.Count() == 9);

   21             UnitOfWork.Finish(true);

   22         }

   23 

   24         [Test]

   25         public void Select_Products_With_Category_Liquor()

   26         {

   27             UnitOfWork.Start();

   28             IRepository<Product> productsRepository = IoC.Container.Resolve<IRepository<Product>>();

   29             var results = from product in productsRepository

   30                           where product.Category == "Liquor"

   31                           select product;

   32             Assert.That(results.Count() > 0);

   33             Assert.That(results.Count() == 4);

   34             UnitOfWork.Finish(true);

   35 

   36         }

So the two tests above just run a simple query, one querying all products and the other querying products with category Liquor. Running them with the Linq to SQL implementation has the following results:

[I have included a LinqRepositorySampleDB database with the sample so you can attach that database to a SQL Express instance to run the tests]

image

That’s encouraging… switching to NHibernate works as well!! A step closer to Persistence Ignorance!

Okay lets spice things up… I have added a OrdersSpecification class that is responsible for dishing out instances of Specification<T> that can be considered as re-usable business logic:

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace LinqRepositorySample.Domain

    7 {

    8     public static class OrderSpecifications

    9     {

   10         public static Specification<Order> OrdersWithHighValue ()

   11         {

   12             return new Specification<Order>(order => order.OrderDetails.Sum(

   13                                                                                 detail => detail.Total

   14                                                                             ) > 200);

   15         }

   16     }

   17 }

Lets see if I can use the OdersWithHighValue specification to query for orders:

   56         [Test]

   57         public void Select_Orders_Not_Delivered_And_OfHighValue()

   58         {

   59             UnitOfWork.Start();

   60             IRepository<Order> ordersRepository = IoC.Container.Resolve<IRepository<Order>>();

   61             var ordersWithHighValue = ordersRepository.Query(OrderSpecifications.OrdersWithHighValue());

   62             var results = from order in ordersWithHighValue

   63                           where !order.Delivered

   64                           select order;

   65 

   66             Assert.That(results.Count() > 0);

   67             UnitOfWork.Finish(true);

   68         }

Lets add some more tests, maybe one that tests adding a new Customer with an Order containing order details for all Liquor items in our product catalog:

   53         public void Select_Order_For_Customer_Returns_Only_Orders_For_Specified_Customer()

   54         {

   55             UnitOfWork.Start();

   56             IRepository<Customer> customersRepository = IoC.Container.Resolve<IRepository<Customer>>();

   57             var customer = (from cust in customersRepository

   58                             where cust.CustomerId == 1

   59                             select cust).First();

   60 

   61             IRepository<Order> ordersRepository = IoC.Container.Resolve<IRepository<Order>>();

   62             var results = from order in ordersRepository

   63                           where order.Customer == customer

   64                           select order;

   65 

   66             Assert.That(results.Count() > 0);

   67             UnitOfWork.Finish(true);

   68         }

   69 

   70        [Test]

   71         public void Adding_New_Customer_With_Order_Saves_Customer_And_Order_To_Database ()

   72         {

   73 

   74             IUnitOfWork uow = UnitOfWork.Start();

   75 

   76             IRepository<Product> productsRepository = IoC.Container.Resolve<IRepository<Product>>();

   77             var liquorProducts = from product in productsRepository

   78                                 where product.Category == "Liquor"

   79                                 select product;

   80 

   81 

   82             Customer customer = new Customer();

   83             customer.FirstName = "Test";

   84             customer.LastName = "Test";

   85             customer.StreetAddress1 = "200 Ventura Blvd";

   86             customer.City = "New York City";

   87             customer.State = "NY";

   88             customer.ZipCode = "99999";

   89 

   90             Order order = new Order();

   91             order.Customer = customer;

   92             order.OrderDate = DateTime.Now;

   93             order.ScheduledDelivery = DateTime.Now.AddDays(5);

   94 

   95             Random rnd = new Random();

   96             foreach (var product in liquorProducts)

   97             {

   98                 OrderDetail detail = new OrderDetail();

   99                 detail.Product = product;

  100                 detail.Qty = rnd.Next(1, liquorProducts.Count());

  101                 order.AddOrderDetail(detail);

  102             }

  103 

  104 

  105             uow.BeginTransaction();

  106             IRepository<Customer> customersRepository = IoC.Container.Resolve<IRepository<Customer>>();

  107             customersRepository.Save(customer);

  108             UnitOfWork.Finish(true);

  109 

  110             //Asserts that ID has been assigned properly.

  111             Assert.That(customer.CustomerId != 0);

  112             Assert.That(order.OrderId != 0);

  113             foreach (var detail in order.OrderDetails)

  114             {

  115                 Assert.That(detail.OrderDetailId != 0);

  116             }

  117         }

Okay, running all tests against both NHibernate and Linq to SQL implementation returns:

image

Perfect!!! There you go true persistence ignorance using RepositoryBase. So now you can use either Linq to SQL or NHibernate as your persistence layer and the rest of your application is completely ignorant of the infrastructure choice.

I have added this sample to Rhinestone’s source code, well I don’t have any other place to upload it to. You can get the solutuion from here (SVN): http://rhinestone.googlecode.com/svn/samples/LinqRepositorySample

Some final comments:

Although the above post shows how Persistence Ignorance can be achieved, this is not entirely true with Entity Framework. EF v1.0 does not have good support for POCO and that’s why I intentionally used Linq to SQL in this sample. Additionally, Linq to SQL itself has it’s own issues. Relying on EntitySet<T> and EntityRef<T> for lazy loading pollutes the domain with infrastructure concerns that I don’t want and Linq to SQL cannot support complex inheritance and value objects. I do believe NHibernate’s mapping is at par with Linq to SQL, sometimes more complex considering the options and flexibility provided by NHibernate, but not having a solid dedicated designer for NHibernate definitely hurts. I know there are designers for NHibernate out there, even code gen tools, I still think that NHibernate would be more widely adopted if there were good designers around to generate the mappings.

Alright, this post has gone long enough.

Reference Links:

http://martinfowler.com/eaaCatalog/unitOfWork.html
http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/10/nhibernate-and-the-unit-of-work-pattern.aspx
http://martinfowler.com/articles/injection.html
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx
http://www.summerofnhibernate.com/


In my previous post I put down some thoughts on the Repository and Specification patterns and in the end said that with the introduction of Linq and the growing popularity of ORM frameworks and their support for Linq, it’s time to look back at these two patterns and see how we can leverage Linq to simplify the patterns and make them infrastructure agnostic.

The goal of this post is to implement infrastructure for a Repository and Specification pattern that achieves the following goals:

  1. We should be able to execute Linq queries directly against the repository.
  2. Implement a specification pattern that allows us to use Expressions as predicates for the specifications.
  3. Implement a specification pattern than allows us to combine specifications (Composite Specification Pattern)
  4. We should be able to query the repository using the Specification pattern.
  5. We should be able to execute Linq queries against the repository directly and also combine the query with specifications.

Creating a base class for all Repositories:

With the above goals the first thing is to start implementing a base Repository interface:

    public interface IRepository<T> : IQueryable<T>

    {

        void Save(T entity);

 

        void Remove(T entity);

    }

The IRepository interface also implements the IQueryable interface allowing us to execute Linq queries directly on the repository. Most repository implementations also have a Load or a Get method that takes in an ID that the repository uses to load the entity. In this case I have omitted those functions since they can be easily represented by Linq queries.

The next step is to implement an abstract base class to make it easy for creating different implementations of the IRepository interface:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

 

    }

So the first thing is to add the Save and Remove methods to the RepositoryBase class as abstract methods. This will allow the child classes to implement the actual functionality of Saving and Removing the entities from the repository:

        #region Implementation of IRepository<T>

        public abstract void Save(T entity);

 

        public abstract void Remove(T entity);

        #endregion

Next we add abstract property to the base class allowing the child class to pass in a IQueryable instance that the base class will use to implement the IQuerable interface:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

        protected abstract IQueryable<T> RepositoryQuery { get;}

Now we can implement members of the IQueryable interface and basically just delegate the calls for IQueryable to the IQuerable isntance that the RepositoryQuery provides us:

        #region Implementation of IEnumerable

        /// <summary>

        /// Returns an enumerator that iterates through the collection.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>1</filterpriority>

        public IEnumerator<T> GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

 

        /// <summary>

        /// Returns an enumerator that iterates through a collection.

        /// </summary>

        /// <returns>

        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>2</filterpriority>

        IEnumerator IEnumerable.GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

        #endregion

 

        #region Implementation of IQueryable

        /// <summary>

        /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable" />.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.Expressions.Expression" /> that is associated with this instance of <see cref="T:System.Linq.IQueryable" />.

        /// </returns>

        public Expression Expression

        {

            get { return RepositoryQuery.Expression; }

        }

        /// <summary>

        /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable" /> is executed.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Type" /> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.

        /// </returns>

        public Type ElementType

        {

            get { return RepositoryQuery.ElementType; }

        }

        /// <summary>

        /// Gets the query provider that is associated with this data source.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.IQueryProvider" /> that is associated with this data source.

        /// </returns>

        public IQueryProvider Provider

        {

            get { return RepositoryQuery.Provider; }

        }

        #endregion

Here’s the full code for the RepositoryBase class:

    public abstract class RepositoryBase<T> : IRepository<T>

    {

        protected abstract IQueryable<T> RepositoryQuery { get;}

 

        #region Implementation of IRepository<T>

        public abstract void Save(T entity);

 

        public abstract void Remove(T entity);

        #endregion

 

        #region Implementation of IEnumerable

        /// <summary>

        /// Returns an enumerator that iterates through the collection.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>1</filterpriority>

        public IEnumerator<T> GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

 

        /// <summary>

        /// Returns an enumerator that iterates through a collection.

        /// </summary>

        /// <returns>

        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.

        /// </returns>

        /// <filterpriority>2</filterpriority>

        IEnumerator IEnumerable.GetEnumerator()

        {

            return RepositoryQuery.GetEnumerator();

        }

        #endregion

 

        #region Implementation of IQueryable

        /// <summary>

        /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable" />.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.Expressions.Expression" /> that is associated with this instance of <see cref="T:System.Linq.IQueryable" />.

        /// </returns>

        public Expression Expression

        {

            get { return RepositoryQuery.Expression; }

        }

        /// <summary>

        /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable" /> is executed.

        /// </summary>

        /// <returns>

        /// A <see cref="T:System.Type" /> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.

        /// </returns>

        public Type ElementType

        {

            get { return RepositoryQuery.ElementType; }

        }

        /// <summary>

        /// Gets the query provider that is associated with this data source.

        /// </summary>

        /// <returns>

        /// The <see cref="T:System.Linq.IQueryProvider" /> that is associated with this data source.

        /// </returns>

        public IQueryProvider Provider

        {

            get { return RepositoryQuery.Provider; }

        }

        #endregion

    }

We can now use this base class to implement child classes and meet our first requirement where we should be able to execute Linq queries directly on the repository. Below are two implementations, one is a Repository that uses a In memory list of Persons while another is a repository that uses a Linq to SQL DataContext (Note: Ideally the DataContext should not be created by the Repository but instead it should either get the DataContext through dependency injection or through a service locator, but for this example creating the DataContext should suffice):

    public class InMemoryPersonRepository : RepositoryBase<Person>

    {

        private List<Person> _persons = new List<Person>();

 

        #region Overrides of RepositoryBase<Person>

        protected override IQueryable<Person> RepositoryQuery

        {

            get { return _persons.AsQueryable(); }

        }

        public override void Save(Person entity)

        {

            _persons.Add(entity);

        }

 

        public override void Remove(Person entity)

        {

            _persons.Remove(entity);

        }

        #endregion

    }

 

    public class LinSqlPersonRepository : RepositoryBase<Person>

    {

 

        private ClassScheduleDataContext _context = new ClassScheduleDataContext();

 

        #region Overrides of RepositoryBase<Person>

        protected override IQueryable<Person> RepositoryQuery

        {

            get { return _context.Persons.AsQueryable(); }

        }

        public override void Save(Person entity)

        {

            _context.Persons.InsertOnSubmit(entity);

        }

 

        public override void Remove(Person entity)

        {

            _context.Persons.DeleteOnSubmit(entity);

        }

        #endregion

    }

So now it’s fairly simple to execute Linq queries directly on the repository:

        public static void Main(string[] args)

        {

            IRepository <Person> repository = new InMemoryPersonRepository();

            var results = from person in repository

                          where person.LastName.Contains("Doe")

                          select person;

        }

Creating a Specification class that allows using Expressions as predicates:

Okay, the next three requirements deal with implementing a Specification pattern that will allow us to use Lambda expressions as predicate. So starting with the interface:

    public interface ISpecification<T>

    {

        Expression<Func<T, bool>> Predicate { get; }

 

        bool IsSatisfiedBy(T entity);

    }

The ISpecificaiton interface has one property Predicate that should return the expression that the specification uses. Now that we have an interface, lets create a generic Specification class that allows creating specification instances:

    public class Specification<T> : ISpecification<T>

    {

        private readonly Expression<Func<T, bool>> _predicate;

 

        public Specification(Expression<Func<T, bool>> predicate)

        {

            _predicate = predicate;

        }

 

        public Expression<Func<T, bool>> Predicate

        {

            get { return _predicate; }

        }

 

        public bool IsSatisfiedBy(T entity)

        {

            return _predicate.Compile().Invoke(entity);

        }

    }

So far so good… the Specification class basically takes in an Expression of Func<T, bool> that it stores in the _predicate field, which it then invokes in IsSatisfiedBy to check if a entity satisfies the specification. Now the third requirement is to allow composing specifications. To provide a clean framework, I’m going to use some operator overloading logic and overload the & and | operators on Specification class:

        public static Specification<T> operator & (Specification<T> leftSide, Specification<T> rightSide)

        {

            var rightInvoke = Expression.Invoke(rightSide.Predicate, leftSide.Predicate.Parameters.Cast<Expression>());

            var newExpression = Expression.MakeBinary(ExpressionType.AndAlso, leftSide.Predicate.Body, rightInvoke);

            return new Specification<T>(

                                    Expression.Lambda<Func<T, bool>>(newExpression, leftSide.Predicate.Parameters)

                                  );

 

        }

 

        public static Specification<T> operator | (Specification<T> leftSide, Specification<T> rightSide)

        {

            var rightInvoke = Expression.Invoke(rightSide.Predicate, leftSide.Predicate.Parameters.Cast<Expression>());

            var newExpression = Expression.MakeBinary(ExpressionType.OrElse, leftSide.Predicate.Body, rightInvoke);

            return new Specification<T>(

                                    Expression.Lambda<Func<T, bool>>(newExpression, leftSide.Predicate.Parameters)

                                  );

        }

What the overloads does is it takes two specifications that need to be combined and creates a new BinaryExpression of the appropriate expression type, that is OrElse or AndAlso, and then returns a new Specification that uses the BinaryExpression as it’s predicate. We can now use the Specification class like so to define our specifications:

    public class CustomerSpecifications

    {

        public Specification<Customer> IsPreferred

        {

            get

            {

                return new Specification<customer>(customer => customer.AverageInvoice > 100000 &&

                                                               customer.AverageQty > 1000);

            }

        }

 

        public Specification<Customer> BuysPremiumPaper

        {

            get

            {

                return new Specification<Customer>(customer => customer.PaperOrdered

                                                                    .Where(paper => paper.Premium == true)

                                                                    .Count() > 100);

            }

        }

    }

And use the above specifications in a Customer entity like so:

    public class Customer

    {

        public bool IsPreferredAndBuysPremium

        {

            get

            {

                return (CustomerSpecifications.IsPreferred &

                        CustomerSpecifications.BuysPremiumPaper).IsSatisfiedBy(this);

            }

        }

 

    }

Integrating the Specification class with RepositoryBase:

Now that we have a way to define re-usable business logic by the way of specifications, lets integrate the Specification class with the RepositoryBase class to allow querying the repository using specifications. First thing is to modify the IRepository interface and add a Query method to it so that returns an IQueryable based on executing the provided specification:

    public interface IRepository<T> : IQueryable<T>

    {

        void Save(T entity);

 

        void Remove(T entity);

 

        IQueryable<T> Query(ISpecification<T> specification);

    }

Next is to implement the Query method on the RepositoryBase class:

        public IQueryable<T> Query(ISpecification<T> specification)

        {

            return RepositoryQuery.Where(specification.Predicate);  

        }

What the Query implementation does is basically uses the Where Linq extension to add the predicate provided by the specification to the IQueryable instance. Now with that done the last two requirements are also complete. Below is an example that shows the various ways we can now use the RepositoryBase and Specification classes to query the repository flexibly:

        public static void Main(string[] args)

        {

            var allCustomersInStateCA = from customer in new CustomersRepository()

                                       where customer.State == "CA"

                                       select customer;

 

            var preferredCustomers = new CustomerRepository.Query(CustomerSpecifications.IsPreferred);

            var preferredCustomersInCA = from customer in preferredCustomers

                                        where customer.State == "CA"

                                        select customer;

 

            var prefferedPremiumCustomers = new CustomerRepository().Query(CustomerSpecifications.IsPreferred &

                                                                          CustomerSpecifications.BuysPremiumPaper);

            var prefferedPremimumCustomersInCA = from customer in prefferedPremiumCustomers

                                                where customer.State == "CA"

                                                select customer;

        }

The above implementation now satisfies all the goals I had set out for the Repository and Specification implementation. I’ve added similar implementations to Rhinestone, so if you would like to get complete source code of the RepositoryBase and Specification classes check out Rhinestone’s source code: http://code.google.com/p/rhinestone/source/checkout.


Okay, time for design pattern thoughts. This time its the Repository pattern. The Repository pattern is a key pattern in Domain driven design, it’s actually specifically mentioned in Evan’s book actually and it’s importance to facilitating DDD cannot be understated. And since Rhinestone is using DDD practices, it only makes sense to use the Repository pattern but even if you are not using DDD and the Repository pattern provides so many advantages that its worth taking a look and perhaps implementing it even for non DDD projects.

So what is a Repository…

The Repository Pattern as a Data Access pattern:

The Repository pattern is defined by P of EAA as:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Okay, it’s a data access component. I get that. But what’s so special about a Repository and how is it any different from any other data access component? The first difference that I see is that a Repository exclusively deals in domain objects. The repository is not a generic data access component that uses Data Access Objects (DAO) or Data Transfer Objects (DTO) patterns. So the repository only accepts domain objects and returns domain objects.

The other difference I can spot from the definition is that a Repository provides a in-memory like collection interface for accessing domain objects. So as far as the consuming component is concerned, it uses the repository just like a collection when working with Domain objects. The repository then neatly abstracts the internal mechanics of how the Add / Remove calls to the repository translate to the actual data access calls to the data store.

So with the repository we get a nice abstraction that provides us with persistence ignorance and a nice separation of concerns where the responsibility of persisting domain objects is encapsulated by the Repository while leaving the domain objects to deal entirely with the domain model and domain logic.

Below is a mock standard Repository interface:

    public interface IProjectsRepository

    {

        Project Get(int projectID);

        Project Load(int projectID);

        void Save(Project project); 

        void Delete(Project project);

    }

That’s simple enough. Nice clean interface that provides a way to get, save and delete Project instances. But, I still don’t see the value add in using the Repository. Or rather I don’t see what’s the BIG advantage of using a Repository pattern. Here I have a simple Get and Load functions to get Project instances (the difference between the two is that Get will throw an exception if a project with that ID is not found) but what if I want to find projects based on some criteria? Lets say I want to find a project that a member belongs to, I’d end up adding this additional method to the Repository:

    public interface IProjectsRepository

    {

        Project Get(int projectID);

        Project Load(int projectID);

        void Save(Project project); 

        void Delete(Project project);

        //Find a project that has the specific user as a member

        Project FindProjectsContainingMember(IUser member);

    }

So as it stands the only advantage a Repository gives me is the encapsulation of logic that handles domain object persistence. So the above FindProjectsContainingMember would encapsulate the logic surrounding how to translate that business language to a data store language that the data store would understand and return the relevant results and finally constructing the domain objects from the returned results.

Back to the definition:

So going back to the definition and write up of the Repository pattern in P of EAA, I see the following explanation of Repository:

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.

[Emphasis mine]

Source: http://martinfowler.com/eaaCatalog/repository.html

Something that piqued my interest is the highlighted line above. Clients construct query specifications and submit them to the Repository for satisfaction… hmmm… so I can declaratively query the repository and have it return business object instances that satisfy that query? Now that is a huge advantage over traditional data access patterns. So does that mean that I don’t have to add additional methods everytime there’s a feature change and I need to query for domain objects using a new criteria? I’M SOLD. Now, the only question is… just how do I do that huh?

Specification and Repository patterns… two peas in a pod:

If you have some time and have an urge to submerge yourself in the dark work of programming patterns, I would highly recommend reading the white paper by Martin Fowler and Eric Evans on the Specification pattern. Otherwise read on…

The Specification pattern in my opinion helps formalizing and declaring criteria as a set of specification that encapsulates business logic. Lets take an example that would make things clearer; a Customer and it’s Preferred property. Say we are building a CRM solution for a famous Paper company down in Scranton, PA where preferred customers are defined as customers who buy more than 1000 reams paper at average in a month and whose Monthly invoiced amount at an average comes to over $100,000.

So looking at the hypothetical business requirement, the first instinct is to add a property to the Customer business object named IsPreferred which might look something like this:

    public class Customer

    {

        public string Name { get; set; }

        public int AverageInvoiced {get; set;}

        public int AverageOrderQty { get; set; }

 

        public bool IsPreferred

        {

            get

            {

                return AverageInvoiced > 100000 && AverageOrderQty > 10000;

            }

        }

 

    }

That seems okay, we have encapsulated the logic of determining a Preferred customer into the Business Entity. Assuming that AverageInvoied and AverageOrderQty are in itself have some business rules on how those two values are calculated, now we just need to query based on that logic… Oh Oh… how do I do that now. So I’ve basically got two options; One is to add a IsPreferred column to the Customers table in the database and store the IsPreferred flag, the other is to create a specialized Stored Proc that queries the database using logic similar to that in the Customer class.

Both options suck! The first one especially sucks because if say the logic changes where preferred customers are customers that now buy 2000 avg. reams of paper and who have been invoiced $200,000 avg. per month, running the query for getting preferred customers based on the Preferred would yield invalid results since customers that still average 1000 reams and $100,000 in invoice are still marked as preferred. The second one is the lesser of two evils but then forces the domain logic to live in the Customer entity and the Stored Proc that is responsible for querying customers based on the preferred status. Now I have my logic spread all over instead of just the domain model… again something that is not acceptable.

The solution… Specifications

Following the specification pattern we can implement a re-usable business logic component that can be passed around to satisfy certain business criteria. As all good patterns, the Specification pattern starts by defining a interface:

    public interface ISpecification<T>

    {

        bool IsSatisfiedBy(T entity);

    }

So the ISpecification interface defines one method, IsSatisfiedBy that takes an instance of the entity type and checks if it satisfies the entity. So now lets define our two criteria, average Invoiced should be greater than $100,000 and average ordered qty should be greater than 1000 into a specification:

    public class CustomerIsPrefferedSpec : ISpecification<Customer>

    {

        #region Implementation of ISpecification<Customer>

        public bool IsSatisfiedBy(Customer entity)

        {

            return entity.AverageInvoiced > 100000 && entity.AverageOrderQty > 1000;

        }

        #endregion

    }

Now this specification can be used in the Customer entity like so:

        public bool IsPreferred

        {

            get

            {

                return new CustomerIsPrefferedSpec().IsSatisfiedBy(this);

            }

        }

Simple enough… but what we can now do is also use this spec and pass it to the repository as a re-usable piece of logic to get Customer instances that match the IsPreferred specification:

    public class CustomerRepository

    {

        IEnumerable<Customer> FindCustomersBySpec (ISpecification<Customer> specification)

        {

            //Logic here to query based on the provided specification.

        }

    }

So now we have a re-usable business logic components that we can use to satisfy a criteria. What if we need to chain the criteria? For example; if we have a need to get all preferred customers that are also buying Grade A category of paper, how do we chain the two criteria together. Here we use the Composite Specification pattern. Below is an implementation of the Composite specification pattern:

    /// <summary>

    /// The generic ISpecification interface.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    public interface ISpecification<T>

    {

        bool IsSatisfiedBy(T entity);

    }

 

    /// <summary>

    /// Base implementation of ISpecification that supports chaining specification

    /// using And and Or chaining.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    public abstract class SpecificationBase<T> : ISpecification<T>

    {

        #region Implementation of ISpecification<T>

        public abstract bool IsSatisfiedBy(T entity);

        #endregion

 

        public SpecificationBase<T> And (ISpecification<T> rightHand)

        {

            return new AndSpecification<T>(this, rightHand);

        }

 

        public Specification<T> Or (ISpecification<T> rightHand)

        {

            return new OrSpecification<T>(this, rightHand);

        }

    }

 

    /// <summary>

    /// Or binary expression specification implementation.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    internal class OrSpecification<T> : SpecificationBase<T>

    {

        private readonly ISpecification<T> _leftHand;

        private readonly ISpecification<T> _rightHand;

 

        public OrSpecification(SpecificationBase<T> leftHand, ISpecification<T> rightHand)

        {

            _leftHand = leftHand;

            _rightHand = rightHand;

        }

 

        #region Overrides of SpecificationBase<T>

        public override bool IsSatisfiedBy(T entity)

        {

            return _leftHand.IsSatisfiedBy(entity) || _rightHand.IsSatisfiedBy(entity);

        }

        #endregion

    }

 

    /// <summary>

    /// And binary expression specification implementatin.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    internal class AndSpecification<T> : SpecificationBase<T>

    {

        private readonly ISpecification<T> _leftHand;

        private readonly ISpecification<T> _rightHand;

 

        public AndSpecification(SpecificationBase<T> leftHand, ISpecification<T> rightHand)

        {

            _leftHand = leftHand;

            _rightHand = rightHand;

        }

 

        #region Overrides of SpecificationBase<T>

        public override bool IsSatisfiedBy(T entity)

        {

            return _leftHand.IsSatisfiedBy(entity) && _rightHand.IsSatisfiedBy(entity);

        }

        #endregion

    }

What the above implementation does is by creating an abstract SpecificationBase, we are ble to add a Or and And methods that return instances of OrSpecification and AndSpecification instances. Now both the OrSpecification and AndSpecification classes inherit from the SpecificationBase abstract class and implement the IsSatisfiedBy method, where all they do is return the evaluation of the right hand specification with the left hand specification.

The end result is we have a nice way to chain and compose specifications together and then also have a Fluent Interface that provides a nice way of specifying the composition.

With the above implementation I can now provide the following hypothetical specifications to a repository and have return the Customer entities that satisfies all the specified criterias:

                IEnumerable<Customer> results = customerRepository.FindBySpec

                                                (

                                                    new IsPreferredSpec()

                                                    .And(new OrdersPaperCategorySpec("Category A"))

                                                    .And(new HasOverduePayments())

                                                );

Right now I’m sure you are thinking about how does the specifications translate to query filtering. One way is to use the yield keyword in a tight loop to return only those results that match the specifications:

        public IEnumerable<Customer> FindBySpec(ISpecification<Customer> specs)

        {

            foreach (var customer in FindAll())

            {

                if (specs.IsSatisfiedBy(customer))

                    yield return customer;

            }

        }

The downside to the above approach is that the filtering and matching of the criteria is done one the entire list of customers that are loaded into memory. The other is to translate the specifications into the data store query language. This is slightly more trickier as you will need to implement some type of Query pattern that is capable translating specifications into the queries that the repository can execute.

A much more saner solution is if you are using ORM solutions such as NHibernate or LLBGenPro, there are ways to specify criteria that implement the Specification pattern which make the job of integrating with the repository a breeze. Heck you can even implement the specification pattern using Lambdas and LINQ and use  Linq to SQL / Entity Framework.

Although by large, Repositories of today ignore the Specification pattern due to the difficulty in implementing a truly persistent ignorant way of translating queries that repositories can just take and run with it. If you are not using an ORM such as NHibernate or LLBGenPro or the numerous others out there that provide inbuilt support for Specifications, it gets hard.

But with Microsoft giving us Linq To SQL and Entity Framework, coupled with Lambdas and LINQ in general, I think we have come to a point where Specifications can be more widely adopted. And with third-party ORM providers now showing major love for Linq we may even come to a completely persistent ignorant solution to defining specifications.

In any case I believe it’s time to take a long hard look at some of the current patterns and how new technologies such as Linq and lambdas provide and how those new advances can be leverages. I think the Repository and Specification patterns are two such patterns that can definitely be overhauled to take advantage of Linq… and that’s what I’ll deal with in my next post. Stay tuned!


Ok, I was wrong, CodePlex sucks balls when it comes to source code. Since I’m in the initial design phases of Rhinestone, there’s bound to be some moving and renaming of source files. One would think that a mature source code control system should be able to handle file and folder moves within the project… one would be wrong!

I have no real experience with Team Foundation server, actually since it’s inception I haven’t had the displeasure to work with it, but if my experience with CodePlex is any kind of of indication I think I wouldn’t like TFS anyway.

I love using Tortoise SVN, and I must say I love how SVN bridge allows me to use Tortoise SVN and Visual SVN and still use the CodePlex servers, but it’s just piss slow. I don’t know if its SVN bridge or CodePlex and I’m definitely sure its a lot faster if you have Team Explorer, I don’t HAVE team explorer to work with. [Donations of VS Team Systems accepted :)]

So now I’ve moved to Google Code. Much better I must say. Check-Ins are much faster, renames are not giving me errors and I can use Tortoise SVN and Visual SVN as is without having to use a bridge to connect to it. Time will tell if Google Code provides a stable source control solution, but for now I’m sticking the source in there, here’s the link: http://code.google.com/p/rhinestone/. So now I’m a happy camper. For CodePlex, all I can say is I wanted to like it… but whenever I checked in changes I always ended up with this expression:

cat
more cat pictures

Well so far I’ve gone without making any specific decisions on the the infrastructure that Rhinestone will depend on and what kind of architecture will I use to design and implement the app.

Out with the old, in with the new

For the most part, all my previous projects, be it commercial or for hobby, have followed the traditional layered architecture where an application is broken down into layers; UI, Business layer, Data Access, etc., where dependencies flowed downwards. Meaning the UI components could only call components in the Business Layer and so on so forth. Violating the rule of downward dependency would mean complicated dependencies where everything is hard wired with everything and soon you end up with an application that has so many inter-crossing dependencies that its hard to do predictive analysis and tell deterministically what components will be called when a code path is executed.

Obviously, try as hard as you might applications designed using the layered architecture most often end up in scenarios where your code starts to look like hopelessly jumbled spaghetti. Even if a layer only depends on the layer beneath it, over time these dependencies get backed in to the application making it difficult to rip out a layer and replace it with another implementation.

The other problem that I always run with layered architecture is the way it is implemented. The implementation is almost always bottom up, meaning you start with a database design then abstract it away by creating a data access layer, on top of which you abstract that away with a business layer that consumes the data access layer, which is then consumed by the UI layer. This always induces a data centric approach to the implementation and causes layers to influence the design of layers they depend on.

What I would like to be the ideal scenario is if I could specify a contract that a layer needs and then have an implementation of that contract provided, that could completely resolve dependency and coupling issues. For example; lets say the UI requires some component to provide it a list of users, and it doesn’t care what specific component provides that list as long as it implements a contract it defines, IUserProvider. And traditionally the wall I hit when trying the above approach is how do I get that specific implementation into my UI layer? As you can tell, I wasn’t aware of Dependency Injection or IoC at that time… now I do.

The above example is achievable using concepts such as Dependency injection and IoC containers. But the moment you start using dependency injection, the concept of downward layers disappear because based on the above example the UI is no longer dependent on some other layer, instead it has specified a contract that it requires to do its job and it is the job of a service locator or IoC container to provide it with a component that satisfies that contract. It’s no longer dependent on any outside component other than itself.

What DI and IoC provide is the ability to break down hard dependency between components and the ability to swap out implementations and evolve the application as it grows in complexity. In the above example I could first provide a component that implements IUserProvider that connects uses a custom membership database to provide it users and then later on provide another implementation that uses AD later on when the app starts to grow. The main point is the UI doesn’t care of the implementation, as long as whatever component it gets it implements the IUserProvider correctly.

Say hello to the Onion Architecture:

I would recommend reading the three-part blog posts from Jeffery Palermo on the Onion Architecture, if you haven’t already,  Part 1, Part 2, Part 3.

Basically, the Onion Architecture is just formally giving a name to existing practices that break away from the traditional layered architecture and use DI and IoC to implement dependency ignorant layers. I will be basically using the Onion Architecture as a reference architecture for Rhinestone.

So based on the Onion Architecture, the core of the application is the domain model… and conveniently Rhinestone already has a domain model to work with :) So the next step would be defining the business and applications service contracts that form up the application core.

Stay tuned… more to follow.

[P.S I’ve stopped titling posts on Rhinestone with Part nos. I realized with the no of posts that I already have on Rhinestone and the pace at which the posts are going I would soon hit a point where I wouldn’t know any more roman numerals to no number the part with… that would be embarrassing.  So instead I have started labeling each post with a Rhinestone tag that you can then use to search on all posts regarding Rhinestone. Here’s the link to see all posts relating to Rhinestone: http://www.codeinsanity.com/search/label/Rhinestone]


Previous Post: Adding Domain logic to Rhinestone using TDD

In my previous post I finished defining the initial domain logic for Rhinestone. Today I decided to setup the database that Rhinestone will use to store it’s data. I have added a db folder to the solution and added a SQL Server database file to it called RhinestoneDB.

image

This way I can continue developing the applicaiton using SQL Express and when I am ready to deploy it I can easily attach the database file to a full blown SQL Server instance. Below is the ER diagram of the initial database design:

image

The table structures follow the domain model closely, but below are some interesting design points:

  1. The database has a single table called WorkItemAttachments table while the domain model splits it into two separate classes; an Attachment entity and a AttachmentFile value object
  2. Related work items in the database is defined by a association table, RelatedWorkItems.

In the next few posts, I'm going to start deciding on the infrastructure and technologies that I will be using to implement the infrastructure and services that the application will require.


[Edit: For some reason the Insert Code Snippet in Live Writer completely screwed up the formatting of the post. I’ve changed the code blocks and used Copy As Html.. add in for VS 2008 to paste code blocks, which I think is much nicer anyways.]

I’ve had a long battle understanding and relying on Test driven development. The first time I heard of TDD, actually read of is more appropriate, was when I read Kent Beck’s Extreme Programming Explained: Embrace Change and Martin Fowler’s Refactoring: Improving the Design of Existing Code. Good books… but the single thought of doing Test first development just seemed to violate the very core of what I knew as programming and software development.

Don’t get me wrong, I absolutely love the ability to define unit tests and I was sold on Unit testing from the get go, no question asked that Unit tests are very valuable when it comes to verifying whether your application does what it should do and are in-dispensable when it comes to maintaining existing software.

But it was TDD that I had a problem with. How can I as a developer write a test for something I haven’t even written in code? There seemed to be a mental barrier that would just prevent me from taking that approach. I had no problems writing unit tests for code that I had already written, which seemed pretty simple cause I know what I am testing for, but not writing tests first.

There’s just no argument that having good unit test coverage on a project tends to provide more reliable and maintainable code. But are there advantages of doing TDD?

What is TDD really?

Test Driven Development is all about test first development. It’s also called Red-Green development where you first write tests for the code you intend to write, see the test fail (Red) and the write the code till you see the test succeed (Green).

If you haven’t tried TDD that above statement is going to look ludicrous to you. How do you write test for code that you haven’t written yet or how CAN you write a test without knowing what you are testing??

I had to struggle with those two questions a lot till recently I forced myself to try doing TDD on a application I was developing for myself.

The answer to both question comes when you realize that what your testing is not code, but the outcome of some code. When it boils down to basics unit tests validate the functional and logical aspect of code by verifying the state that code affects and the result by executing the code.

Lets take an example;

Lets say you have a class Employee that encapsulates an employee in your application and you need to add logic to Employee that will allow the consumers of Employee to know if the Employee instance has achieved seniority status. This status is achieved when the Employee the employee has had over 20 years of service in the organization.

So following TDD, before even touching the Employee class the first thing to do would be to open up your unit test project, open the file that contains tests for the Employee class (or create one if it doesn’t exist) and then write tests that may look like this:

    7     [TestFixture]

    8     public class EmployeeTests

    9     {

   10         [Test]

   11         public void IsSenior_Should_Return_False_When_Total_Years_Is_10 ()

   12         {

   13             Employee emp = new Employee();

   14             emp.DateJoined = new DateTime(1998, 1, 1);

   15             Assert.That(emp.IsSenior, Is.False);

   16         }

   17 

   18         [Test]

   19         public void IsSenior_Should_Return_True_When_Total_Years_Is_21 ()

   20         {

   21             Employee emp = new Employee();

   22             emp.DateJoined = new DateTime(1988, 1, 1);

   23             Assert.That(emp.IsSenior, Is.True);

   24         }

   25     }

After I have defined my tests, I go ahead and implement a property in Employee called IsSenior and add logic in it that satisfies both tests.

   27     public class Employee

   28     {

   29         public DateTime DateJoined { get; set; }

   30 

   31         public bool IsSenior

   32         {

   33             get

   34             {

   35                 var diff = DateTime.Now - DateJoined;

   36                 return (diff.TotalDays/365) > 20;

   37             }

   38         }

   39     }

What are the advantages of TDD:

Writing your test first and then writing the code to satisfy the tests has many advantages;

  • By writing your tests first, you codify and formalize the specification of the code you will write to satisfy your tests. In the above example, I have formally defined the inputs the method might encounter and the end results that the method should give back. So when it comes time to implement the IsSenior property, you know exactly what you need to achieve with the property.
  • Writing tests first allow you to spot potential problems or issues before implementation. Sometimes writing tests first can uncover design issues well before implementation which would allow saving time. Many times after implementing some code you find that there is a design issue that would require refactoring of other components after which you may have to come back to your implementation and refactor that as well. TDD catches these situations well before hand allowing you to address the issue before implementation.
  • TDD acts as a metric that indicates when the implementation is complete. Have you ever had that feeling when after you write a method you think its does what it does but don’t really know if it does what SHOULD do? Seeing tests go from red to green is a visual indicator to let you know that the implementation is complete, your method does what it SHOULD do… stop coding.
  • Less F5 development. Everyone has done testing that involved starting the application in the debugger and invoking various parts of the app using the UI to test some new functionality. This becomes a pain because anytime you make a change you have to do the same act of firing up the debugger, test, see the exception that occurred, change code, starting up the app in debugger again, test, see the exception that occured… ad infinitum. TDD lets you skip the debugger when testing non-UI layers (Note: there are UI test runners for almost all UI platforms now. But those are more integration tests than unit tests)
  • Good TDD practices lead to more reliable and maintainable code. Having code implementation that are developed on basis of tests automatically make them reliable, cause well they are testable. TDD also provides higher maintainable code because the unit tests provide a safety net when updating parts of the application. If you break something that alters the expected behavior of the application, those tests will let you know.

TDD lifecycle:

TDD follows a lifecycle, which if followed tends to produce highly reliable and maintainable code. This life cycle is:

  1. Write tests: Add test(s) for functionality you would like to implement. Even if the functionality is completely new and code doesn’t exist, such as a class or method you have not created, still write the tests. The test(s) have to fail.
  2. Run the tests (Red): Run the tests you have created to verify that the tests fail.
  3. Write the implementation: Write the implementation that satisfy the tests you wrote in step 1.
  4. Run the tests (Green): Run the test(s) again, they should succeed. If they don’t the implementation does not satisfy the test(s), go back to the implementation and fix it. Run the tests again and again till they succeed.
  5. Refactor: Refactor your code to clean up implementation details. Perhaps while implementing the code you found that the code is violating a design principle or could be better implemented using a different pattern, in that case refactor. You use the previous tests to ensure that the refactoring does not alter the expected behavior of the code.
  6. Repeat: You’re done implementing this functionality, repeat the steps for additional functionality or enhancements.

The “Writing tests take up time…” argument:

This is by far the most vocal argument to TDD these days. Programmers that have not taken a deeper look at unit testing and TDD, when hearing about TDD or unit tests for the first time, the first argument is: “You expect me to write some tests and waste time on that while I have to deliver stuff on time? So are you going to give me more time to write these tests? No… then I won’t bother.”

Yes TDD does take some time, initially. When starting out TDD for the first time it takes time adjusting your thinking towards writing test first. But once you get accustomed to writing tests first, the time taken to writing tests then implementing is marginally higher than time taken to implementation only.

The reason why there is only a slight time difference is because TDD clarifies what you are going to implement before you implement it. It’s a form or Contract first development where you define the contract of what you need to achieve, then go ahead and implement it with the full knowledge of what needs to be done to achieve it.

And there is no doubt that it saves time by skipping the need to fire up the application for verification that your code works. You can trust that if your tests are written with the right expectations and they pass… your code works.

But my argument in the end is, even if TDD does indeed take slightly more time, it’s worth it. The advantages of having reliable and highly maintainable code clearly outweighs the fact that it might take slightly more time. And at the end of the day… my job is to develop highly reliable and maintainable code…

posted @ Monday, August 04, 2008 6:58 PM | Feedback (0) | Filed Under [ TDD ]

Domain Driven Design – What, How, Huh?

Domain Driven Design is hot these days, its so hot that there’s an entire movement going on in the ALT.Net group to make Microsoft refocus it’s attention to giving us good support for domain first development as opposed to data first development, the Entity Framework No Confidence Vote being an example (Disclaimer: I am a signatory on the Entity Framework No Confidence Vote. Although I don’t fully support the language used in the vote and some of the comments from the ALT.Net community, it should be thought of as a message to Microsoft. More on this later).

So is DDD, that’s the acronym by the way, something that has recently cropped up? Is it some shiny new technology that automatically makes my applications better? Will it sing for me? In all counts no… especially the last one.

DDD is a methodology first proposed by Eric Evans as a way to approach software development and he wrote a book about it on 2004, Domain-driven Design: Tackling Complexity in the Heart of Software. I read this book back in 2004 along with the now famous POEAA book by Martin Fowler, and even then it was a hard concept to grok as it wasn’t an API or a pattern that I could grasp my mind around. It’s a methodology, a mentality with which you approach how you develop software. It has taken me 4 years to finally understand the concepts DDD proposes and see the value proposition in implementing it. As they say… “I finally see the light”.

DDD is about best practices, guidance and a specific set of design guidelines that aim at making the art of creating applications successful, in both delivery and maintenance. Lets face it, software development is an art, and unfortunately most of that art doesn’t see the light of day because the allocated budget or time gets overshot or due to un-maintainable applications because they get overly complex and the more common reason, it doesn’t work or it doesn’t do what it was meant to do.

So what is DDD really. To understand DDD, lets take the two fundamental premises of DDD(taken from http://domaindrivendesign.org/)

  • For most software projects, the primary focus should be on the domain and domain logic; and
  • Complex domain designs should be based on a model.

The first premise sets the foundation for the second. If you get the first premise, you automatically realize the need for the second premise. And the first premise is the hardest to grasp.

As a developer my thinking naturally leans towards thinking about data. Well after all at the heart of all applications, be it business or research or a space computer calculating trajectories for landing on the moon, they all deal with data… at one way or another. You tend to think of applications in terms of data coming in, data being passed around to another component to do work, data resulting from an method call… data… data… data (flashback from StarTrek Next Generation)

Based on the first premise my primary focus should be on the domain and the domain logic. Big words them… but what does domain mean?

Focusing on the domain and domain logic as opposed to data

The domain is the specific problem or requirement you are attempting to solve by creating a software application. Every software endeavor begins from a need to solve, simplify a process or fulfill a need. DDD proposes to design the software on the basis of that domain.

So the guideline that DDD lays down is to let the domain of the application dictate its direction. Which if you come to think of it is not so different from how you would build an application today. You have a problem to solve, and you build the application to solve that problem. The difference comes about in how you look at solving that problem.

In DDD your focus is on the Domain Entities and the logic behind these domain entities. Every developer, knowingly or un-knowingly, has created entities. If you ever created a Customer, Order or a similar object that is uniquely identifiable based on one or more representative values then you’ve created an entity. An entity is a participant in the application, an identifiable participant that code acts on, e.g. Customer. But DDD puts focus on Domain Entities. Let that sink in a while… Domain Entities. What are domain entities? Entities that participate in your domain are called Domain Entities. Simple isn’t it.

It’s very easy to think of business objects as domain entities while they are far from it. It’s so easy to create a customer business object that has private fields to encapsulate it’s data, has properties that expose this information and then has methods that persist that customer instance to the store and methods to perform validation on itself. Does that make it a domain entity?

The answer is no. Simply because there was no thought process around finding how the customer object fits in the domain model and contribute to the domain. Each domain entity is designed in regards to the entire domain model and its interactions with other domain entities, all aimed at representing the domain in it’s entirety

Introducing the domain model – the ubiquitous language

The second premise says that complex domain designs should be based on a model. This model that the premise talks about is the domain model. A domain model is nothing but the act of creating a model that satisfies the problem domain. It is a model that maps the different domain entities in a software application, their encapsulating logic and the various interactions between these entities.

Do not make the mistake of thinking that the domain model is the same as a class structure diagram, because that’s the first mistake I made when I started out on DDD. A class structure diagram is a UML diagrams that specifies a standard way to describe class structures and their associations with other classes, and defining the inheritance hierarchy. So how is a class diagram any different from a domain model? DDD takes the purist approach to its model and leaves out any concerns that does not deal with the domain. That means that anything that doesn’t directly contribute to the domain is not part of the domain model. A class structure diagram has no such restriction.

Okay, so right now you might be asking the question how is this any different from how I develop my applications right now? I have objects, that I’ve identified as entities, and they have logic behind them such as validation and what not… how is DDD any different?

Domain driven design is the process of software development through the identification of the problem domain, the identification and design of the domain entities that participate in the domain, designing the domain model that acts as the core of the application and finally satisfying the domain by designing and developing the consumers of this domain, such as UI components.

Think about the above statement, implementing DDD means that you don’t think about persistence, services, infrastructure, etc. instead focus on just representing your problem domain as a domain model which then forms the basis of ubiquitous language used to communicate with the stakeholders of the application regarding the domain. Once you have formed your domain model, you then satisfy the problem domain by consuming that domain model in your UI or services or what ever form that satisfies the problem domain.

The term ubiquitous language when applied to the domain model refers to the fact that this domain model forms the basic language when taking about the domain between different stake holders. Have you ever been in that position where you are in a meeting with a domain expert and he says “accounts recievable” and you say “customer"? That happens because there is no common language between the two and there are more chances for miscommunication or misunderstanding. Having a domain model vetted and used by all stakeholders helps forming a common language that is used by all when communicating matters regarding the domain.

Reading material

Domain driven design is a big topic and requires a shift in thinking. The best way to get started on domain driven design is to read Eric Evans book Domain-driven Design: Tackling Complexity in the Heart of Software. Below are some additional links that may help:"

http://domaindrivendesign.org/ – The official DDD group web site
http://www.infoq.com/interviews/jimmy-nilsson-domain-driven-design# – Jimmy Nilsson on DDD
http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202 – Applying Domain Driven Design Patterns book.
http://www.lostechies.com/blogs/joe_ocampo/archive/2007/04/02/a-discussion-on-domain-driven-design.aspx – A nice article on domain driven design.

So what’s next?

In the next post I will start laying out the domain model for Rhinestone and provide rationale behind the design process that I take identifying the domain, the domain entities and the model itself.


Previous Post: Rhinestone (Part II) – Defining the project scope

In the previous post I defined the goal of the project and identified the actors that will be using the application, in this post I will start specifying the feature set of Rhinestone.

Normally, in real life projects, the initial feature set are identified through project reviews, user feedback and interviews and requirement analysis, but since this isn’t a real life project I get to decide the feature set of the project… a refreshing change.

SIDE NOTE: YAGNI and KISS for defining feature sets:

One of the few principles that I have started using in my work related projects is YAGNI (You aint gonna need it) and KISS (Keep it simple stupid) and believe me they work. YAGNI helps especially when you are creating a library of reusable components that other developers will be using to do their job. The tendency is to build everything in that library, including the kitchen sink. What you end up doing is adding a lot of defunct and dead code that nobody uses. Following the YAGNI principle, you add additional functionality only when you need to and not up front. This helps reduce design overhead and relies heavily on refactoring to introduce new features when the need arises.

KISS is an old principle, which is a derivative of Occam’s Razor. Using KISS you always look for the simplest and non complex solution that works, which normally turns out to be the right solution. KISS is important to keep your code less complex which leads to better maintainability. Of course sometimes the simplest solution is to hack some piece of code VBA style, but KISS is always used in conjunction of design practices and design principals.

I find that using YAGNI and KISS while defining feature sets for projects also works. YAGNI helps rule out features that aren’t necessary to meeting our immediate project goals and provides a way to implement features as and when the need arises. Whereas KISS keeps our feature requirements simple and not making features overly too complex, again keeping in mind our original project goal.

But before I start laying down the feature set of the project some background info on BDD and why use BDD for defining feature sets.

What is BDD?

Behavior driven design is a methodology, much like Domain Driven Design (which I’ll get to in a later post), that provides guidance on how to execute your projects. BDD focuses on defining and laying out a behavior specification for your application. BDD uses a set syntax that is well understood by all involved in project development, testing and execution and provides a basis of communication so that everyone is on the same page.

I see BDD as a different way to specifying software requirements. As opposed to the convoluted approach of defining a Software Requirement spec, designing arcane UML diagrams containing class, sequence, state, etc. diagrams, BDD uses a text based specification that uses natural language to define specifications.

BDD specifications or more aptly stories can also be thought of specialized Use Case modeling. Use Cases are used to define the scope and boundaries of applications and show the interactions between the actors and use cases but rarely do they specify the resulting rationale behind those interactions. A BDD story specifies the rationale behind a behavior, which in turn forms the result of that behavior or action and provides a foundation for unit tests.

A standard BDD story looks like this:

As a [actor] I want to [action] so that [rationale]

The [actor] defines the initiator or requestor of the behavior. This initiator is normally a user interacting with the application, but if the behavior is being specified for a component meant to be used by other software components, the [actor] is clearly defined as the consumer component that can initiate this action.

The [action] defines the actual behavior. This is what defines what action to take when this behavior is initiated by the [actor]

The [rationale] defines why this [action] is being taken place by the [actor].

Lets take a look at a sample behavior spec in relation to Rhinestone:

As a [Project Developer Or Administrator Or Project Owner] I want to [update a work item’s status] so that [I can specify when a work item is In Progress, Completed, Closed, Canceled And I can inform the submitter of this update]

The above behavior spec clearly defines the interaction of a project developer, administrator or a project manager (the actors) when they update a submitted work item (the action) and the result of the action where the work item is set to one of the statuses listed above and the original submitted of the work item is notified (the rationale).

BDD also uses natural language key words such as Or and And to chain actors or rationales but never the action. Each behavior story can only define one action.

I’ll talk more about BDD and its relation to test driven development (TDD) in future posts but for this post BDD is being discussed in the context of defining feature sets in terms of BDD stories.

Using BDD stories as Feature sets:

In my view using BDD stories leans naturally towards specifying feature sets of projects. The stories are un-ambiguous, clear, concise and is defined in a natural language that can be understood by all. This also allows developers to then use BDD frameworks, such as NBehave, to specify constraints on the stories and TDD approach while developing the application.

So now that I have decided to use BDD stories to define my feature sets, as opposed to standard UML diagrams, I am going to add a Feature Stories.txt file to the docs folder of the solution. This file will contain the over all feature set I would like to implement in the project.

Below is just one feature set that I have added to the project so far, you can get view the others in the source:

As a registered user, I would like to login, so that I can see the top 10 work items I have submitted.

The above BDD story is simple enough and doesn’t require additional explanation on what the feature set is. It identifies the actor, which is the Registered user, what action does the actor take, which is the act of logging in, and why the actor is performing the action which becomes the result of the action, which is showing a list of to top 10 work items the registered user has submitted.

The next few posts are going to deal with defining the domain and DDD and implementing the Domain Model for the project.


Previously: Rhinestone (Part I) – Setting up project folder structure and source control

In my previous post I set up the basic folder structure of the project for Source control and also created an empty Visual Studio solution in which I will be adding individual projects. In this post I primarily define the scope and purpose of the project.

Defining the project goal:

I start out almost every project by defining a goal for the project, and if I’m lucky this goal remains the same and doesn’t get muddled with extra concerns and eventual un-used functionality creep. I haven’t been that lucky in any of my work related projects. For some reason its the nature of Business Analysts or project owners to start adding functionality to the project that has nothing to do with the original goal or intention of the project. But I digress…

So here is the goal of project Rhinestone:

The goal of project Rhinestone is to allow registered users and applications to submit work items or issues to project owners / members, allowing project owners / members to review, prioritize and work on the submitted issues.

That’s short and sweet isn’t it. The above goal statement succinctly defines the scope of the project without introducing specifics so that the overall goal doesn’t get muddled in with specific implementation or feature details. Leaving out specific feature information is very intentional because this goal statement is meant to be used when evaluating the feature set of the application later on. I’m sure you’ve had those meetings where someone, normally a project owner or BA, comes up with an awesome idea / feature for the project (or at least they think its awesome) which really has nothing to do with the project… and because its sooo awesome that the above mentioned BA’s or Project Owners mandate that feature to be implemented because if it weren’t implemented it would be the end of the world.

The project goal acts as a sanity check when reviewing the feature set of the application. Anything that doesn’t have any impact on achieving the goal gets thrown out the window and those that do are reviewed for impact.

Identifying the actors:

Identifying the “Who are going to use this application” is a very important step in the initial design phases of an application. In other words, what are the actors that are going to act on this application. An actor need not be a physical user, they could be other applications. In our case our goal statement conveniently provides us a preliminary list of actors that would use Rhinestone:

  1. Registered User
  2. Applications
  3. Project Owners
  4. Project Members
  5. Administrator

Although the last actor, Administrator, was not mentioned in the project goal it makes sense to add one since many setup or administrative tasks pertaining to maintenance needs to be performed by someone. Hence the Administrator actor.

So now that I have a project goal and identified actors that will be using this project, I have added two text files in the solutions docs folder; Goal.txt and Actors.txt that contain the Goal statement and identified actors respectively.

image

In the next post I will start specifying the feature set of the project and introduce using BDD as a way of specifying stories as feature sets.


I’ve chosen CodePlex as opposed to Sourceforge as the host for the project. I’ve used Sourceforge for a previous, now dead, project and it works great, but for Rhinestone I wanted to try out CodePlex.

Setting up Rhinestone on CodePlex

Setting up a project at CodePlex was quite easy. Register an account, activate the account and sign in, Create a project, give it a description and your done. You get 30 days to publish the project, and the project must have checked in files, otherwise your project gets automatically removed from the server.

CodePlex uses TFS Version Control as the source control provider which means that to interact with it you have the following options:

  1. Have a version of Visual Studio Team System that has Team System Explorer inbuilt that can interact with CodePlex’s TFS
  2. Use the now non-supported CodePlex Client.
  3. Use something called Teamprise from a third party vendor, which is an external standalone client software to interact with CodePlex’s TFS
  4. Use SvnBridge to connect to CodePlex’s TFS and use a SVN Client such as Tortoise SVN.

I used the last option since I already have good experience on SVN and use Tortoise SVN daily at work for my projects and I’m too cheap to get a Team System version of VS.

SvnBridge acts as a tunnel between Tortoise SVN and TFS and maps SVN commands that come from SVN clients such as Tortoise SVN to commands understood by TFS. Setting up SvnBridge is quite simple and you can follow the instructions here on how to set it up.

Here is the link to the project at CodePlex: http://www.codeplex.com/rhinestone

Laying out the project folder structure

I don’t know about anyone else but whenever I’ve been tasked to start a new project, the first debate that goes in my mind is the project folder structure. Selecting a folder structure for your solutions and projects is a personal preference and after many trial and errors over the years I have settled a standard folder structure that I use for my solutions. You can see the top level folder structure I have created for Rhinestone on the following screen shot:

image

The top level folder structure follows the standard folder layout recommended for SVN projects. The trunk folder contains the main working trunk of the solution. The branches folder is meant to hold different branches that work off the trunk, and if the project is complex enough I add sub folders in there to identify feature and mock sub folders to identify branches that are legitimate feature development branches as opposed to random testing branches.

The purpose of the tags folder is to allow storing of releases from the trunk. Whenever a release is made, a branch is made from the trunk into the tags folder with a version no. This allows easy access to old releases when necessary.

Within the trunk folder, I have broken down the folder structure further into docs, libs, src and tests folders.

The docs folder is where I store documentation pertaining to the project, such as behavior specs, UML diagrams, drawings, ER diagrams… in short anything that can count as documentation for the project.

The libs folder is where shared or third party libraries are stored and then referenced by projects. The reason third party libraries are added to source control is to allow all developers working on a project to have identical versions of third party libraries. This reduces version mismatch problems and build breaks when a developer using a different version of a third party library checks in his / her project.

The src folder contains the main source of the project. Under src there will be multiple sub folders for each Visual Studio project created for the solution.

The tests folder is self explanatory. This is where unit test and integration projects are stored.

Setting up the VS Solution

So now that I have the folder structure I want for my project, I can go ahead and create the Visual Studio solution. I’ve created an empty VS solution and added Solution folders that mimic the trunk folder structure.

image

So far I’ve setup a project in CodePlex, defined the top level layout of the project and created the solution, in future posts I’ll start setting up the projects and start defining the scope and specs of Rhinestone.


With a lot going on at work and my personal life I’ve had very little time to think about what to write on this blog, and whenever I tried sitting down to write a post I would hit a solid brick wall when trying to think about what to write.

While traveling to Toronto recently, I was trying to think up of ideas on what to write on the blog and I found that the thing I really wanted to do most was to develop an application / website from scratch using new development practices and technologies that I have been itching to try out. Hence project Rhinestone was born.

Rhinestone is a work item / issue tracking web application that can be customized and used by anyone for their projects. Although there are plenty of such OSS solutions out there, Trac being one that I have used in a consulting project previously, but I wanted something fairly simple that can be tweaked and customized for specific purposes. I have not made any decisions on what technologies to implement Rhinestone with, primarily because I feel that decisions such as what platform and technologies to use for a project are better thought off once you have a better understanding of what the scope of the project is and the domain problem it solves.

In the upcoming posts I will go in detail on the development of Rhinestone.


Some talk on Unit testing frameworks:

We’ve come a long way in having rich Unit test support in .net. I remember the time when NUnit was the only framework that was viable for providing good unit test support. Now we have so many unit testing frameworks, each with it’s unique advantages that it’s getting hard to decide which framework to choose.

Apart from NUnit, we have MBUnit (now Gallio), xUnit, csUnit, MSTest (Microsoft’s unit testing framework that now comes bundled with almost all editions of VS).

In my opinion, I would not recommend using MSTest, even though there’s a huge temptation to do so because of the nice built in test runner and test reports. MSTest is dog ass slow… try running about 2000 tests in one test session and you will know how slow it is. Compared to NUnit or MBUnit it’s a joke. Another reason is because MSTest doesn’t implement some of the advances in Row testing, combatorial and Pair-wise testing that frameworks like NUnit, MBUnit do (Although NUnit has had the ability to perform parameterized tests using additional addins, v2.5 currently in Alpha 3 has inbuilt support for parameterized, combatorial and pair-wise testing). And if they do intend to add that support, I have to wait close to 2 years to get that while other frameworks have moved on providing even better functionality.

Right now my preferred unit testing framework remains NUnit. With 2.5 I finally am able to run parameterized tests like MBUnit’s RowTest and I just love NUnit’s fluent interface.

Adding tests and logic to Rhinestone.

So now that I have a preliminary definition of my domain model, its time to start adding some meat to it. So keeping in line with TDD practices, I have added a Rhinestone.Domain.Tests project under the tests\unit\ solution folder:

image

I’ve added test fixtures in this project that test the domain entities, namely; AttachmentFile, Attachment, Comment, Project and WorkItem.

Even though AttachmentFile is a Value Object, it still requires testing to ensure that data is being properly captured. Right now the logic on the domain model mainly relies on setting the correct associations when attachments or comments are added to a WorkItem instances and some logic surrounding when a project owner is defined for a Project instance.

An example of business logic added to the domain, consider the following logic; when a project owner is set on a Project instance, that owner should be part of the Project’s members, if not already. And when removing the project owner that user should not be removed from the project members list automatically.

Implementing the above logic is fairly straight forward, but lets do this the TDD way. So first I write a test. The first test I have written is to ensure that if a null reference is passed to the Owner property, then it should throw an ArgumentNullException:

   61         [Test, Description("Tests that setting the Owner property of Project will throw an ArgumentNullException.")]

   62         public void Setting_Owner_With_Null_Throws_ArgumentNullException()

   63         {

   64             var project = new Project();

   65             Assert.Throws<ArgumentNullException>(() => project.Owner = null);

   66         }

Okay, now that I have this test, I run it to make sure that it fails.

image

I am using ReSharper’s awesome Test Runner here. If you don’t have ReSharper I would highly recommend getting a trial copy from here and try it out.

Okay, so now that the test fails, lets make it pass. Here is the implementation of the Owner property on Project so far:

   55         /// <summary>

   56         /// Gets a <see cref="IUser"/> that is the owner of the project.

   57         /// </summary>

   58         /// <value>The <see cref="IUser"/> that is the owner of the project.</value>

   59         public virtual IUser Owner

   60         {

   61             get { return _owner; }

   62             set

   63             {

   64                 Guard.Against<ArgumentNullException>(value == null, "Cannot set a null IUser instance as the owner of a project.");

   65 

   66             }

   67         }

Here I’m using the Guard utility class I posted about yesterday (here) to check for an ArgumentNullException scenario.

Okay so now the test passes:

image

Great. The next test I want to write is to make sure that when I set the a user as the Owner of a project, that owner is also added to the Member’s list of the project. Here’s the test:

   68         [Test, Description("Tests that setting a user as the Owner of a project adds that" +

   69                            " user as a member of the project in the Members list.")]

   70         public void Setting_Ower_Adds_Owner_To_The_Members_List ()

   71         {

   72             var mockUser = MockRepository.GenerateStub<IUser>();

   73             var project = new Project();

   74 

   75             Assert.That(project.Members.Count(), Test.Is.EqualTo(0));

   76 

   77             project.Owner = mockUser;

   78 

   79             Assert.That(project.Owner, Test.Is.SameAs(mockUser));

   80             Assert.That(project.Members.Count(), Test.Is.EqualTo(1));

   81             Assert.That(project.Members.First(), Test.Is.SameAs(mockUser));

   82         }

Note: I am using Rhino.Mocks here to provide mocking support. If you are not familiar with mocking, I recommend reading this article by Martin Fowler for more info. I’ll be posting more about mocking soon as well.

And the implementation to make that test pass:

   55         /// <summary>

   56         /// Gets a <see cref="IUser"/> that is the owner of the project.

   57         /// </summary>

   58         /// <value>The <see cref="IUser"/> that is the owner of the project.</value>

   59         public virtual IUser Owner

   60         {

   61             get { return _owner; }

   62             set

   63             {

   64                 Guard.Against<ArgumentNullException>(value == null, "Cannot set a null IUser instance as the owner of a project.");

   65                 _owner = value;

   66                 AddMember(_owner);

   67             }

   68         }

The other test is to make sure that when I set a new owner on the project, the old owner should not be removed from the members list:

   84         [Test, Description("Tests that setting the Owner property to a new owner will not" +

   85                            " remove the old owner from the Members list.")]

   86         public void Setting_New_Owner_Does_Not_Remove_Old_Owner_From_Members_List ()

   87         {

   88             var mockUser1 = MockRepository.GenerateStub<IUser>();

   89             var mockUser2 = MockRepository.GenerateStub<IUser>();

   90 

   91             mockUser1.Stub(call => call.UserName).Return("user1").Repeat.Any();

   92             mockUser2.Stub(call => call.UserName).Return("user2").Repeat.Any();

   93 

   94             var project = new Project();

   95             project.Owner = mockUser1;

   96             project.Owner = mockUser2;

   97 

   98             Assert.That(project.Members.Count(), Test.Is.EqualTo(2));

   99             Assert.That(project.Members.Contains(mockUser1));

  100             Assert.That(project.Members.Contains(mockUser2));

  101             Assert.That(project.Owner, Test.Is.SameAs(mockUser2));

  102         }

The above test passes from the start, which is Ok because the implementation of the Owner property already satisfies the test.

One thing you will note is that I am not checking for duplication, meaning what happens if I set the same instance of IUser as the owner twice, won’t I end up with the same IUser instance twice in the Members list? Lets write a test for this:

  104         [Test, Description("Tests that setting the Owner property twice with the same user instance" +

  105                            " will not add the user twice in the members list.")]

  106         public void Setting_Same_Owner_Twice_Does_Not_Add_Owner_Twice_In_Members_List()

  107         {

  108             var mockUser1 = MockRepository.GenerateStub<IUser>();

  109 

  110             mockUser1.Stub(call => call.UserName).Return("user1").Repeat.Any();

  111 

  112             var project = new Project();

  113             project.Owner = mockUser1;

  114             project.Owner = mockUser1;

  115 

  116             Assert.That(project.Members.Count(), Test.Is.EqualTo(1));

  117             Assert.That(project.Members.Contains(mockUser1));

  118         }

This test automatically succeeds, the reason being that the Members list is a HashSet<T> in the Project entity. HashSet<T> is a new collection in .Net 3.5 that has provides functionality to add only unique instances into the collection, so I get duplicate instance checking out of the box.

So far I have almost 90% test coverage on my domain. Next step… infrastructure.