Domain-Driven Design with Linq & ORM – Part 2
In my last post about DDD & Linq (1.5 month ago … oops), I showed the following piece of code:
ServiceLocator.Register<IUnitOfWorkFactory, NHibernateUnitOfWorkFactory>();
using (UnitOfWork.Start())
{
ITransaction tx = UnitOfWork.Current.BeginTransaction(IsolationLevel.ReadCommitted);
try
{
IRepository<Customer> cr = UnitOfWork.Current.GetRepository<Customer>();
Customer customer = cr.FindOne(c => c.Id == "AROUT");
customer.Address = "125 Hanover Sq.";
cr.Save(customer);
tx.Commit();
}
catch
{
if (tx != null) tx.Rollback();
}
finally
{
if (tx != null) tx.Dispose();
}
}
After thinking about it, refactoring it 10 times, I sat down this morning and finally got it the way I wanted (don’t ask me why it took so long lol):
// Configure your favorite IoC container:
// - Register an IUnitOfWorkFactory
// - Register an IRepositoryFactory
// - Register a generic IRepository<TEntity>
// (your container must support open generic types).
// - Configure your container to use the IRepositoryFactory
// to create instances of the IRepository<TEntity> component
// (your container must support factories).
// Once your IoC container is set up, configure it as the ServiceProvider
// (must implement the IServiceProvider interface or use a wrapper) for the ServiceLocator helper
ServiceLocator.ServiceProvider = container;
// Start a unit of work
using (IUnitOfWork uow = UnitOfWork.Start())
{
// Get an instance of repository
IRepository<Customer> cr = ServiceLocator.GetService<IRepository<Customer>>();
// Retrieve data with a Linq query
Customer customer = cr.FindOne(c => c.CustomerID == "AROUT");
// Modify retrieved entity
customer.Address = "000 Hanover Sq.";
// Ask repository to save changes
cr.Save(customer);
// Mark the unit of work as complete to propagate changes to data source
uow.Complete();
}
The re-worked IRepository<T> looks like this:
public interface IRepository<TEntity> : IDisposable where TEntity : class
{
long Count();
long Count(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void Add(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void Remove(IEnumerable<TEntity> entities);
void RemoveAll();
void RemoveAll(Expression<Func<TEntity, bool>> predicate);
void Save(TEntity entity);
void Save(IEnumerable<TEntity> entities);
TEntity FindOne(Expression<Func<TEntity, bool>> predicate);
IEnumerable<TEntity> FindAll();
IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate);
IQueryable<TEntity> QueryAll();
IQueryable<TEntity> QueryAll(Expression<Func<TEntity, bool>> predicate);
}
I think it looks better
I currently have UoW & Repository factories for the following ORM:
- NHibernate
- ActiveRecord
- LinqToSql
- EntityFramework
The code is still very experimental, relies a lot of Castle Project‘s libraries (some might view it as a pro, others a con …), and I unfortunately don’t have much time to work more on it. If there is any interest for it, I might drop it online in its current state (basic samples, no unit test, code analysis spitting out a lot of warnings).
Feedback is welcomed.
Possible Improvements:
- For simplification purpose, I might remove the dependency to a ‘ServiceProvider‘ and instead define a simple ‘UnitOfWork.Configure‘ method where we can specify the type of the IUnitOfWorkFactory & IRepositoryFactory.
- Should the IUnitOfWork interface expose a ‘GetRepository<TEntity>‘ method to get rid of the ugly static call to ‘ServiceLocator.GetService<IRepository<T>>‘ ?



Hi,
This looks interesting. If you can provide a copy of the source code, it will be very helpful.
thanks,
Arun
Hi Steve
Can you provide me a copy of the code too?
Thanks in advance
Marcel