Alex Rivera | Logout

Using a Generic Repository pattern with fluent nHibernate

Asked 2010-04-06T20:15:34.170
13

I'm currently developing a medium sized application, which will access 2 or more SQL databases, on different sites etc...

I am considering using something similar to this: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

However, I want to use fluent nHibernate, in place of Linq-to-SQL (and of course nHibernate.Linq)

Is this viable?

How would I go about configuring this? Where would my mapping definitions go etc...?

This application will eventually have many facets - from a WebUI, WCF Library and Windows applications / services.

Also, for example on a "product" table, would I create a "ProductManager" class, that has methods like:

GetProduct, GetAllProducts etc...

Any pointers are greatly received.

Edit
Report

1 Answer

21

In my opinion (and in some other peoples opinion as well), a repository should be an interface that hides data access in an interface that mimics a collection interface. That's why a repository should be an IQueryable and IEnumerable.

public interface IRepository<T> : IQueryable<T>
{
  void Add(T entity);
  T Get(Guid id);
  void Remove(T entity);
}

public class Repository<T> : IQueryable<T>
{
  private readonly ISession session;

  public Repository(ISession session)
  {
    session = session;
  }

  public Type ElementType
  {
    get { return session.Query<T>().ElementType; }
  }

  public Expression Expression
  {
    get { return session.Query<T>().Expression; }
  }

  public IQueryProvider Provider
  {
    get { return session.Query<T>().Provider; } 
  }  

  public void Add(T entity)
  {
    session.Save(entity);
  }

  public T Get(Guid id)
  {
    return session.Get<T>(id);
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return this.GetEnumerator();
  }

  public IEnumerator<T> GetEnumerator()
  {
    return session.Query<T>().GetEnumerator();
  }

  public void Remove(T entity)
  {
    session.Delete(entity);
  }   
}

I do not implement a SubmitChanges like method in the repository itself, because I want to submit the changes of several repositories used by one action of the user at once. I hide the transaction management in a unit of work interface:

public interface IUnitOfWork : IDisposable
{
  void Commit();
  void RollBack();
}

I use the session of an NHibernate specific unit of work implementation as session for the repositories:

public interface INHiberanteUnitOfWork : IUnitOfWork
{
  ISession Session { get; } 
}

In a real application, I use a more complicated repository interface with methods for things like pagination, eager loading, specification pattern, access to the other w

answered 2010-04-06T21:56:57.393

Your Answer