2

I am using unity, entity framework 4 with POCO classes, repository pattern for DAL and services for Business Logic control. I also want to use Unit of Work so I can package together CRUD operations which I perform on different services and then commit them all together.

My question is what would be the proper way to inject the Unit Of Work mechanism into my application using Microsoft Unity? I understand that I can put the IUnitOfWork together with the repository on the constructor of the proper service and then if Unity mapping is specified it would auto initiate the proper instances, but this way I do not pass the global unit of work but rather create a new instance on each level, which can't be a smart way to do it (actually the repository is initiated even before the service).

What am I missing? (Attached is constructor code as I wrote it now of service and its repository).

U also understand that I can use Unity's ParameterOverrides method to take some global instance of Unit of Work (lets say from my aspx.cs file) and pass it into the service and then into the repository. But it seems a bit lame. Is this my only option?

Thanks

public class GenericRepository<T> : IUnitOfWorkRepository, IGenericRepository<T> where T : BaseEntity, IAggregateRoot
{

    private IUnitOfWork _uow;

    /// <summary>
    /// Returns the active object context
    /// </summary>
    private ObjectContext ObjectContext
    {
        get
        {
            return ObjectContextManager.GetObjectContext();
        }
    }

    public GenericRepository(IUnitOfWork uow)
    {
        _uow = uow;
    }

    //blahhhh...

    public void Add(T entity)
    {
        _uow.RegisterNew(entity, this);
    }

    public void Delete(T entity)
    {
        _uow.RegisterRemoved(entity, this);
    }

     //.....blah blah....

    public void PersistCreationOf(IAggregateRoot entity)
    {
        this.ObjectContext.AddObject(GetEntitySetName(), entity);
    }

    public void PersistUpdateOf(IAggregateRoot entity)
    {
        // Do nothing as EF tracks changes
    }

    public void PersistDeletionOf(IAggregateRoot entity)
    {
        this.ObjectContext.DeleteObject(entity);
    }
}

public class CategoryRepository : GenericRepository<XComSolutions.FB.Domain.Model.Entities.Category>, ICategoryRepository
{
    public CategoryRepository(IUnitOfWork uow)
        : base(uow)
    {   }
}

public class CategoryService : ICategoryService
{
    public int myID {get; set;}

    private ICategoryRepository _categoryRepository;
    private IUnitOfWork _uow;

    public CategoryService(ICategoryRepository categoryRepository,
        IUnitOfWork uow)
    {
        _categoryRepository = categoryRepository;
        _uow = uow;
    }

    public List<Category> GetAll()
    {
        return _categoryRepository.GetAll();
    }
}
Sagi
  • 1,572
  • 5
  • 18
  • 28
  • Check this: http://stackoverflow.com/questions/5187562/mvc-ef-datacontext-singleton-instance-per-web-request-in-unity/5191797#5191797 It discusses how to use lifetime managers with Unity. If you have problem to understand something add it to your question. At the moment I don't see how do you resolve services. – Ladislav Mrnka Mar 07 '11 at 18:50
  • Have you got an answer to this question, Sagi? – Blaise Oct 30 '12 at 15:16

2 Answers2

3

Define an IUnitOfWorkFactory and inject that in your services:

public class Service
{
    private readonly IUnitOfWorkFactory factory;

    public Service(IUnitOfWorkFactory factory)
    {
        this.factory = factory;
    }

    public void DoOperation()
    {
        using (UnitOfWork context = this.factory.CreateNew())
        {
            this.DoSomeStuff(context);
            this.DoMoreStuff(context);

            context.SubmitChanges();
        }
    }
}
Bern
  • 7,102
  • 5
  • 31
  • 46
Steven
  • 151,500
  • 20
  • 287
  • 393
0

What I think you need to do is to define unit of work factory. You register this factory with your DI container and you resolve for this factory every time you need your unit of work. Then you get unit of work from the factory, work with it and let it go. You often will see that you need your unit of work within a scope of single method or single class. This article discuss Unit of Work pattern in connection with Entity Framework: http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

Andrew Savinykh
  • 22,530
  • 13
  • 90
  • 143