Introduction

In this article, I will show an implementation of dependency injection, repository and unit of work patterns using Castle Windsor as DI (dependency injection) container and NHibernate as ORM (Object Relational Mapping) tool.

Dependency Injection: Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time [1]

Repository: Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. [2]

Unit of work: Used to define and manage transactional jobs in your application. [4]

You can find many resources, articles and tutorials on dependency injection and unit of work. So, I'll not define them here. This article will be focused on solution of problems described in the next section.

Problems

When you are developing a data-driven application, you consider some design principles. In this section, I'll describe them and explain the solution briefly.

How to open/close connections

First problem is that: How and where to open and close connections. Surely, it's best to manage connections in database layer (probably in repositories). So, we can open connection, run database command and close connection in every repository method call. This may be inefficient and useless if we want to share same connection on different methods of same repository or different methods of different repositories (Think a transaction that uses some methods of different repositories).

If we are bulding a web site (ASP.NET MVC or Web Forms), we can open the connection on Application_BeginRequest and close it on Application_EndRequest. But this approach has some disadvantages:

We open/close database for every request even if some request does not use database. So, a connection is taken from connection pool for a while even if it's not used.

We open database at the beginning of the request and close it at the end. But, there maybe cases the request is very long and database operation takes a short time in that request. Again, an inefficient usage of connection pool.

Issues described above may not be big problems for you (indeed, for me, they are problems). But if you are not developing a web site, if you are developing a windows service that runs many threads those are using database in some periods of time? So, where to open/close connection.

How to manage transactions

If you are using transactions (most of applications do that) in your database operations, where to begin, commit or rollback the transaction.
You can not do in repository methods since your transaction may include many different repository method calls.
So, your business layer (that calls the repository methods) can begin/commit/rollback transactions. There are some problems in this approach:

Your business layer includes database specific codes. This breaks single responsibility and layering.

This approach dublicates transaction logic in every business method.

As I described in the previous section, you can use Application_BeginRequest and Application_EndRequest to manage transactions. Same problems are here again: You can begin/commit unnecessary transactions. Also, you must handle errors and rollback transactions when needed.

Also, if you are not developing a web site, it's hard to find a good place to begin/commit/rollback transactions.

So, best approach is to begin a transaction when you really need to begin, commit the transaction when and only if all of your operations succeed and the rollback transaction if any of your operations fail. In this article, I implemented right this approach.

Implementation

Entities

In our implementation, Entity is mapped to a record in a database table. In domain driven design (DDD), Entity is a persistent object that has a unique identifier [3]. All Entities in our solution is derived from Entity class defined below:

An entity has a unique identifier (primary key) that's type can be different (int, long, guid...), so it's a generic class. Our entities (People, Phone, City...) are derived from this class. For example, People class is defined as below:

Entity mappings

ORM tools (like Entity framework and NHibernate) requires definition of mapping of Entities to database tables. There are many ways to implement it. I used NHibernate Fluent API to accomplish that. So, we define a mapping class for all entitites as shown below for People entity:

Repositories (Database layer)

Repositories [2] are used to create database layer to abstract data access logic from upper layers. Generally a repository class is created for each entity (or aggregation: group of entities). I created a repository for each entity. First, I defined an interface that must be implemented by all repository classes:

///<summary>/// This interface must be implemented by all repositories to ensure UnitOfWork to work.
///</summary>publicinterface IRepository
{
}
///<summary>/// This interface is implemented by all repositories to ensure implementation of fixed methods.
///</summary>///<typeparamname="TEntity">Main Entity type this repository works on</typeparam>///<typeparamname="TPrimaryKey">Primary key type of the entity</typeparam>publicinterface IRepository<TEntity, TPrimaryKey> : IRepository where TEntity : Entity<TPrimaryKey>
{
///<summary>/// Used to get a IQueryable that is used to retrive entities from entire table.
///</summary>///<returns>IQueryable to be used to select entities from database</returns> IQueryable<TEntity> GetAll();
///<summary>/// Gets an entity.
///</summary>///<paramname="key">Primary key of the entity to get</param>///<returns>Entity</returns> TEntity Get(TPrimaryKey key);
///<summary>/// Inserts a new entity.
///</summary>///<paramname="entity">Entity</param>void Insert(TEntity entity);
///<summary>/// Updates an existing entity.
///</summary>///<paramname="entity">Entity</param>void Update(TEntity entity);
///<summary>/// Deletes an entity.
///</summary>///<paramname="id">Id of the entity</param>void Delete(TPrimaryKey id);
}

Thus, all repository classes must implement methods listed above. But, implementation of these methods are almost same in NHibernate. So, we can define a base class for all repositories. Thus, we don't implement same logic for all repositories. See NhRepositoryBase defined as below:

Session property is used to get session object (database connection object in NHibernate) from NhUnitOfWork.Current.Session. This gets the right Session object for current running transaction, so repositories does not think how to open/close connection and transaction. This mechanism will be explained in later sections.

As you see, all CRUD operations are implemented for all repositories as default. So, now we can create a PersonRepository that can select, delete, update and create records just declaring types shown below:

We can do same for Phone and City entities. If we want to add a custom repository method, we can just add it to related entitiy's repository. For instance, we can add a new method to PhoneRepository to delete phones of given person:

Static Current property is the key point of the class. As you see, it gets/sets _current field that is marked as ThreadStatic [5]. So, we can use same Unit of work object in same thread. Thus, we can share same connection/transaction between objects. Lastly, we define an attribute that is used to mark a method which must be transactional:

///<summary>/// This attribute is used to indicate that declaring method is transactional (atomic).
/// A method that has this attribute is intercepted, a transaction starts before call the method.
/// At the end of method call, transaction is commited if there is no exception, othervise it's rolled back.
///</summary>[AttributeUsage(AttributeTargets.Method)]
publicclass UnitOfWorkAttribute : Attribute
{
}

If a method must be transactional, we just mark it with UnitOfWork attribute. Then we will intercept these methods using dependency injection as described later.

Service layer

In Domain Driven Design, Domain services is used to implement business logic. It can use repositories to perform database tasks. For example, PersonService is defined as below:

Focus on usage of UnitOfWork attrbiute defined in the previous section. DeletePerson method is marked as UnitOfWork. Because it calls two different repository methods and these method calls must be transactional. On the other hand, CreatePerson is not UnitOfWork since it only calls one repository method (Insert of person repository) and this repository method can open/close (manage) it's own transaction. We will see how to implement it in next sections.

Dependency injection

Dependency Injection (DI) Containers (like Castle Windsor we use) is used to manage dependencies and lifecycles of object is your application. So, it helps you to build loosely coupled components/modules in your application. It's generally initialized on startup of your application. In an ASP.NET application, global.asax is the mostly used place to initialize it:

We create a WindsowContainer object (this is the main object to use dependency injection) on application startup and dispose it at the end. In InitializeWindsor method we also change default controller factory of MVC to use dependency injection. So, whenever ASP.NET MVC needs a Controller (in every web request), it creates it using DI [6]. See http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx to learn Castle windsor. Here, our controller factory:

It's pretty simple and describes itself. The important part is to inject our own object dependencies. It's accomplished by PhoneBookDependencyInstaller class. This class is automatically investigated by Castle windsor since it implements IWindsorInstaller. Remember the _windsorContainer.Install(FromAssembly.This()); line in global.asax file.

As you see we are registering all components using Windsor's Register method. Notice that we are registering all repository classes with single line. We do same for services and controlles. We're using factory method to create ISessionFactory that is used to create ISession (database connection) objects to use with NHibernate. Finally, at the begining of Install method, we register to Kernel's ComponentRegistered event to inject our interception logic. See Kernel_ComponentRegistered method. If a method is a repository method, we are always using interception for it. Also, if a method has marked with UnitOfWork attribute, it's also intercepted with our NhUnitOfWorkInterceptor class.

Interception

Interception is a technique to run some codes at the begining of a method call and at the end of the method call. It's generally used for logging, profiling, caching... etc. Using this technique you can dynamically inject your codes into desired methods without changing the method.

We use interception to implement Unit of work. If a method is repository method or marked as UnitOfWork attribute (explained in previous section), we open a database connection (Session on NHibernate) and begin a transaction at the begining of the method. If no exception is thrown by the intercepted method, the transaction is commited at the end of the method. If the method throws any exception, whole transaction is rolled back. So, let's see NhUnitOfWorkInterceptor class to know how I implemented it:

The main method is Intercept. It first checks if there is a transaction started before for this thread. If so, it does not starts a new transaction, uses the current transaction (see NhUnitOfWork.Current). Thus, nested calls to methods those have UnitOfWork attribute can use/share same transaction. A transaction is created/commited in only first entrance of a unit of work method. Also, if a method is not transactional, it just calls the method and returns. invocation.Proceed() command perform a call to the intercepted method.

If there is no transaction currently, we must start a new transaction and commit the transaction if no error, rollback the transaction on an error case. Finally we set the NhUnitOfWork.Current = null to allow to start other transactions for current thread later if needed. You can also see UnitOfWorkHelper class.

Thus, the only open/close connection and begin/commit/rollback transaction codes in entire application is defined in only one point.

Web Application

I developed a simple phone book application using the patterns described above. It's an ASP.NET MVC application. So, server side is implemented by ASP.NET MVC Controllers, client side is implemented using HTML and Javascript.

To run application, first create the database using PhoneBookDb.sql file in the solution (it requires SQL Server 2008 R2 or a newer version). Then check the connection string in web.config if you change the name of the database.

Also, it may require to Enable Nuget Package Restore to restore nuget packages.

Server side

In our application (for demonstration purposes), we define just one controller: HomeController. It gets needed services in it's constructor. Castle Windsor injects these services into controller since we registered service classes and MVC controller factory to Windsor.

As you see, we use JSON objects to communicate with the client. Web page makes AJAX request to this controller to perform CRUD (Create, Retrive (select), Update and Delete) operations. See source codes for other actions.

Client side

Client side is HTML and Javascript. I implemented client side using jTable [7]. It's a jQuery plugin that is developed by me. It automates listing of database records and update/create/delete forms. See jtable.org for more information. See source codes for implementation. Here is the result:

Console Application

In this section, I'll show how to implement all techniques (mentioned above) for a console application. I created a simple console application that periodically runs, checks and deletes all people who are older than 120 age (Think that I don't want to store old people in my phone book). This is just an example for services those run on background and performs some tasks. It may be a console application or a background Windows Service. Does not matter. Here, our main class that prepares and runs dependency injection and starts our periodically running service:

In the Start method, we initialize the Castle Windsor container. Then we are registering dependencies using Installers. See source codes for Program.cs that uses PhoneBookRunner class. PhoneBookDependencyInstaller registers main components of our application. I also added a new installer for this console application:

As you see, DeletePeopleOlderThan120Age is a UnitOfWork method. So, it runs as transactional.

More

If you did like the patterns and techniques in this article, you will also like ASP.NET Boilerplate application framework. It implementes all techniques described in this article. It open source and distributed on nuget..

Share

About the Author

I have started programming at 14 years old using Pascal as hobby. Then I interested in web development (HTML, JavaScript, ASP...) before university.

I graduated from Sakarya University Computer Engineering. At university, I learned C++, Visual Basic.NET, C#, ASP.NET and Java. I partly implemented ARP, IP and TCP protocols in Java as my final term project.

Now, I am working in a private company in Istanbul as a senior software architect & developer. Working on Windows and web based software development using C# and ASP.NET MVC.

I am thinking to use your approach along with entity framework and .Net Transaction Scope, but in this implementation you open new transaction when call any of repository’s method (if no transaction was already opened), but for those method that just query DB we do not need to open transaction, right? I am thinking to change the code so

NhUnitOfWork.Current.BeginTransaction();

will be called only if it is in context of UoW. to make this work all services APIs that might update the DB should be UoW.

//Intercept all methods of all repositories.
if (UnitOfWorkHelper.IsRepositoryClass(handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(NhUnitOfWorkInterceptor)));
}

If I want to use ninject then what to do instead of this code to make every repository call a transaction?

First, what's Commit attribute? It's not related to this article. It must be UnitOfWork. If this method is a repository method, it's intercepted automatically.

To prevent that, you can define a NoDb attribute and check it in NhUnitOfWorkInterceptor's RequiresDbConnection method. Check it and return false. Thus, RegisterAddRetunNewId does not opens connection, instead RegisterPatient opens.

I use Commit to call SaveChanges in the infrastructure. I don't use UoW attributes in repositories, but only in services.
I just wanted to save changes in RegisterPatient and then return the new Id from RegisterAddRetunNewId.
But when I call the RegisterPatient method from RegisterAddRetunNewId, even though it has the CommitAttribute the interceptor isn't involved (thus SaveChanges is not called).
So I think that interception occurs when the method is called from the "outside"

To implement a custom membership provider, just inherit from MembershipProvider class then override ValidateUser method. In this method, you can use a UserRepository to check the user account. So, you need a User entity and UserRepository. Nevertheless, this is not in the scope of this article.

//Intercept all methods of all repositories.
if (UnitOfWorkHelper.IsRepositoryClass(handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(NhUnitOfWorkInterceptor)));
}

is it possible instead of unit of work class to use some IoC facility (for eg. Autofac registration per Http request - in case of web application), so ISession is instantiated every time per web request?

I used Castle Windsor, It has also PerWebRequest lifetime but i did not want to use it since it opens session for every web reequest even if you dont perform database operation. So, my approach is more effective. But if you want to use it, it's simpler, you can find nice articles about it.