HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Interface for unit of work pattern and repository pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
interfaceworkforrepositoryandpatternunit

Problem

I'm trying to design a well defined yet simple interface for the unit of work and repository patterns. My UoW's are exposed to services and services then "get repositories" that it needs to query. I know returning IQueryable for repositories is a religious war. Because repositories are only exposed to the service, all queries are performed inside the service and therefore I can test the queries. Is there anything I should change for these interfaces? All criticisms are greatly appreciated!

public interface IUnitOfWork : IDisposable
{
    bool IsActive { get; }

    bool WasCommitted { get; }

    /// 
    /// Commits all changes made on the unit of work.
    /// 
    void Commit();

    bool WasRolledBack { get; }

    /// 
    /// Rolls back all changes made on the unit of work.
    /// 
    void Rollback();

    /// 
    /// Returns an instance of an entity with the specified key that is attached to the unit of work without
    /// loading the entity from a repository.
    /// 
    /// 
    /// 
    T Load(int id)
        where T : class;

    void Attach(T entity)
        where T : class, IIdentifiable;

    void Detach(T entity)
        where T : class;

    IRepository GetRepository()
        where T : class;
}

public interface IRepository
    where T : class
{

    IUnitOfWork UnitOfWork { get; }

    void Add(T entity);

    void Remove(T entity);

    /// 
    /// Returns an instance of an entity with the specified key that is attached to the unit of work by loading
    /// the entity from the repository.
    /// 
    /// 
    /// 
    T Get(int id);

    IQueryable All();
}

Solution

I think your interfaces are mostly well-defined, with a couple exceptions:

I don't think Load, Attach and Detach should be members of IUnitOfWork, but rather IRepository. It seems that the repository that manages objects of type T would be the best place to place methods that acts on that type.

The UnitOfWork property on IRepository does not belong there. Things that modify one repository shouldn't be allowed to go and get other repositories to modify on their own. If they need them, pass them in explicitly. Otherwise, you're hiding from potential callers the fact that your implementation actually depends on more than just the one repository, and hiding your dependencies like you're ashamed of them is one of my least favorite code smells.

Context

StackExchange Code Review Q#276, answer score: 3

Revisions (0)

No revisions yet.