Search code examples
nhibernategenericsfluent-nhibernaterepositoryrepository-pattern

Single repository with generic methods ... bad idea?


I'm currently trying out a few different ways of implementing repositories in the project I'm working on, and currently have a single repository with generic methods on it something like this:

public interface IRepository
{
    T GetSingle<T>(IQueryBase<T> query) where T : BaseEntity;

    IQueryable<T> GetList<T>(IQueryBase<T> query) where T : BaseEntity;

    T Get<T>(int id) where T : BaseEntity;

    int Save<T>(T entity) where T : BaseEntity;

    void DeleteSingle<T>(IQueryBase<T> query) where T : BaseEntity;

    void DeleteList<T>(IQueryBase<T> query) where T : BaseEntity;
}

That way I can just inject a single repository into a class and use it to get whatever I need.

(by the way, I'm using Fluent NHibernate as my ORM, with a session-per-web-request pattern, and injecting my repository using Structuremap)

This seems to work for me - the methods I've defined on this repository do everything I need. But in all my web searching, I haven't found other people using this approach, which makes me think I'm missing something ... Is this going to cause me problems as I grow my application?

I read a lot of people talking about having a repository per root entity - but if I identify root entities with some interface and restrict the generic methods to only allow classes implementing that interface, then aren't I achieving the same thing?

thanks in advance for any offerings.


Solution

  • I'm currently using a mix of both generic repositories (IRepository<T>) and custom (ICustomRepository). I do not expose IQueryable or IQueryOver from my repositories though.

    Also I am only using my repositories as a query interface. I do all of my saving, updating, deleting through the Session (unit of work) object that I'm injecting into my repository. This allows me to do transactions across different repositories.

    I've found that I definitely cannot do everything from a generic repository but they are definitely useful in a number of cases.

    To answer your question though I do not think it's a bad idea to have a single generic repository if you can get by with it. In my implementation this would not work but if it works for you then that's great. I think it comes down to what works best for you. I don't think you will ever find a solution out there that works perfectly for your situation. I've found hybrid solutions work best for me.