Archive

Posts Tagged ‘Rhino’

Domain-Driven Design with Linq & ORM

May 1st, 2008 stiiifff 2 comments

We all now that an ORM plays an important role in a DDD architecture … but it would be nice if we could write our Domain Model without being tightly coupled to our favorite ORM tool, especially the code we write in Repositories. Thanks to Linq, we already have a way to abstract our queries (our ORM 'just has to' support Linq, anyway that's a requirement for a good ORM nowadays). The other thing we should be able to abstract is the object, specific to each ORM, that is the interface with the persistence layer, that keeps track of the changes on entities, the 'context' or the 'session' object.

Well, most ORM tools are implementing similar Patterns, namely UnitOfWork, IdentityMap, LazyLoad … so it is fair to assume that it should be possible to build an abstract layer that would allow us to work at a higher level, and have providers for our favorite ORM tools.

Here is a sample from some early code I wrote:

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();
    }
}

The Repository interface, which makes heavy use of Linq to express query criterions, looks like this:

public interface IRepository<TEntity> where TEntity : class
{
    long Count();
    long Count(Expression<Func<TEntity, bool>> predicate);
    void Delete(TEntity entity);
    void Delete(IEnumerable<TEntity> entities);
    void DeleteAll();
    void DeleteAll(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> ProjectAll();
    IQueryable<TEntity> ProjectAll(Expression<Func<TEntity, bool>> expression);
}

Wanna use LinqToSql or EntityFramework instead of NHibernate … well, that’s easy, just change the first line to:

ServiceLocator.Register<IUnitOfWorkFactory, LinqToSqlUnitOfWorkFactory>();

or

ServiceLocator.Register<IUnitOfWorkFactory, EntityFrameworkUnitOfWorkFactory>();

Nice isn’t it ? ;)
We can also have:

ServiceLocator.Register<IUnitOfWorkFactory, ActiveRecordUnitOfWorkFactory>();

or

ServiceLocator.Register<IUnitOfWorkFactory, EussUnitOfWorkFactory>();

Well, I think you get the point.
So, what you think ? Suggestions & remarks are welcome.

“Not invented here” disclaimer: This code is largely inspired and based on code from Castle Project & Rhino.Commons. I just generalized it.

“Pre-Pre-Pre-Pre-Pre Alpha code” disclaimer: This code is quite experimental, it is not (yet) fully unit-tested and doesn’t support (yet) all the capabilities of the different ORM tools presented here.

Using Castle Windsor in your custom Workflow Activities

January 8th, 2008 stiiifff No comments

A little trick about accessing your Windsor container, containing e.g. your infrastructure services, from your custom activities :)

Castle.Windsor assembly contains a Castle.Windsor.Adapters.ComponentModel namespace with some very interesting & usefull classes …

To get access to my container from my custom activities, here is the approach I choose:

  • Encapsulate my container in a ContainerWrapper (this class does not assume ownership of the wrapped IWindsorContainer).
  • Add the wrapper to the WorkflowRuntime with the AddService method.
  • Access my container through the activity's ActivityExecutionContext (which implements the IServiceProvider interface) by calling the GetService method with IContainerAccessor (or IServiceProvider) as type.

IMHO, Simple & nice :)

This little trick also allows to use a test container containing mocked services for your unit tests … much easier than if your custom activities were accessing the container through a static service locator or a similar static helper class.

Hope this little trick can save you some valuable time ! ;)