views:

65

answers:

1

Over the past week or so I have been reading a lot of articles and tutorials regarding the repository pattern. A lot of the articles closely tie the repository pattern to the unit of work pattern. In these articles, I usually find code similar to this:

interface IUnitOfWork<TEntity>
{
    void RegisterNew(TEntity entity);
    void RegisterDirty(TEntity entity);
    void RegisterDeleted(TEntity entity);

    void Commit();
    void Rollback();
}

interface IRepository<TKey, TEntity>
{
    TEntity FindById(TKey id);
    IEnumerable<TEntity> FindAll();

    void Add(TEntity entity);
    void Update(TEntity entity);
    void Delete(TEntity entity);
}

class Repository : IRepository<int, string>
{
    public Repository(IUnitOfWork<string> context)
    {
        this.context = context;
    }

    private IUnitOfWork<string> context;

    public void Add(string entity)
    {
        context.RegisterNew(entity);
    }

    public void Update(string entity)
    {
        context.RegisterDirty(entity);
    }

    public void Delete(string entity)
    {
        context.RegisterDeleted(entity);
    }

    /* Entity retrieval methods */
}

Am I understanding correctly that the unit of work object is meant to handle the addition, update, or deletion of any object in the underlying data store (in my case, a directory service which I communicate with via LDAP)? If that's true, shouldn't it handle the retrieval of any objects as well? Why is that not part of the suggested UoW interface?

+2  A: 

A Repository is in charge of the data - getting it, updating and the other CRUD operations, providing persistence ignorance.

A Unit Of Work (uow), as Marin Fowler says:

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.

The uow will coordinate multiple operations on objects - it may or may not use repositories in order to persist these changes.

Oded
So, when a the method `Repository.Add(obj)` is called, the change is registered with the unit of work object. Then, when `unitOfWork.Commit()` is called, the Repository retrieves the pending operations from the unit of work and performs them?
Justin R.
@Justin R. - sounds about right, though the details may depend on implementation.
Oded
If the logic for committing changes lies within the repository object, and the unit of work simply tracks the pending changes, then how is the unit of work any different from a simple collection of pending changes? And why would it have its own Commit/Rollback methods (as suggested in Martin Fowler's UoW interface)?
Justin R.
@Justin R - it pretty much _is_ a change tracker with the added ability to commit and rollback the whole set of changes as a _single unit of work_ (it is also supposed to work across transactions).
Oded
I guess that's where I get confused. It sounds like the responsibilities of a unit of work object are nearly identical to those of a repository object. I feel like I am missing something.
Justin R.
@Justin R. - I see. Think of it as a mediator between _several_ repositories.
Oded