Question

I'm in my first time with DDD, so I'm begginer! So, let's take it's very simple :D I developed an application using asp.net mvc 2 , ddd and nhibernate. I have a domain model in a class library, my repositories in another class library, and an asp.net mvc 2 application. My Repository base class, I have a construct that I inject and dependency (my unique ISessionFactory object started in global.asax), the code is:

public class Repository<T> : IRepository<T>
    where T : Entidade
{
    protected ISessionFactory SessionFactory { get; private set; }
    protected ISession Session
    {
        get { return SessionFactory.GetCurrentSession(); }
    }

    protected Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }        

    public void Save(T entity)
    {
        Session.SaveOrUpdate(entity);
    }

    public void Delete(T entity)
    {
        Session.Delete(entity);
    }

    public T Get(long key)
    {
        return Session.Get<T>(key);
    }

    public IList<T> FindAll()
    {
        return Session.CreateCriteria(typeof(T)).SetCacheable(true).List<T>();
    }
}

And After I have the spefic repositories, like this:

public class DocumentRepository : Repository<Domain.Document>, IDocumentRepository
{
        // constructor
        public DocumentRepository (ISessionFactory sessionFactory) : base(sessionFactory) 
        { }

        public IList<Domain.Document> GetByType(int idType)
        {
            var result = Session.CreateQuery("from Document d where d.Type.Id = :IdType")
                .SetParameter("IdType", idType)
                .List<Domain.Document>();

            return result;
        }
}

there is not control of transaction in this code, and it's working fine, but, I would like to make something to control this repositories in my controller of asp.net mvc, something simple, like this:

using (var tx = /* what can I put here ? */) {
   try 
   {
     _repositoryA.Save(objA);
     _repositoryB.Save(objB);
     _repositotyC.Delete(objC);
     /* ... others tasks ... */

     tx.Commit();
   }
   catch
   {
     tx.RollBack();
   }
}

I've heared about NHibernateUnitOfWork, but i don't know :(, How Can I configure NHibernateUnitOfWork to work with my repositories ? Should I change the my simple repository ? Sugestions are welcome!

So, thanks if somebody read to here! If can help me, I appretiate!

PS: Sorry for my english!

bye =D

Was it helpful?

Solution

There is an excellent library called NCommon (source) that provides a great UnitOfWork implementation built right in. Version 1.1 allows you to do something like:

public class Foo
{
    private readonly IRepository<Stuff> _repository;

    public Foo(IRepository<Stuff> repository)
    {
         _repository = repository;
    }

    public void DoSomething()
    {
        using (var scope = new UnitOfWorkScope())
        {
           _repository.Save(a);
           scope.Commit();
        }
    }
}

It integrates with the latest NHibernate and even uses NHibernate.Linq to provide some powerful querying features. You have little or nothing to build yourself and it works great out of the box.

Edit:

I elaborated on my example to show the full recommended way to use NCommon in a project with dependency-injection.

OTHER TIPS

Session is NHibernate's unit of work. But you can always create your own abstraction of it.

using (var tx = Session.BeginTransaction) { ...

You can make the Session on your Repository a public property. Then you can do the following:

using(var tx = _repository.Session.BeginTransaction())

On a somewhat related note, this should all be inside of a service layer, not in your controller. Then the controller should have references to your services.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top