views:

818

answers:

2

Hi,

Ok so I 'm just getting into nhibernate (using fluent).

One thing that I love about it is that I can use the Repository pattern (read about it from the nhibernate rhino blog).

Basically using generics, I can create methods that will work accross ALL my database tables.

 public interface IRepository<T>
    {
        T GetById(int id);
        ICollection<T> FindAll();
        void Add(T entity);
        void Remove(T entity);
    }


 public class Repository<T> : IRepository<T>
    {

        public ISession Session
        {
            get 
            { 
                return SessionProvider.GetSession(); 
            }
        }


        public T GetById(int id)
        {
            return Session.Get<T>(id);
        }

        public ICollection<T> FindAll()
        {
            return Session.CreateCriteria(typeof(T)).List<T>();
        }

        public void Add(T t)
        {
            Session.Save(t);
        }

        public void Remove(T t)
        {
            Session.Delete(t);
        }    

    }

I then inherit the Repository class and I can then add methods that are specific to that entity.

When trying to add an Update method, someone mentioned that the Repository pattern is suppose to act on collections? Am I looking at things incorrectly here? Why can't I create an update method?

I tried adding a update method, but I'm confused as to how I will handle the session and update the database?

I want a single place for all my database access for each entity, so UserRepository will have all basic CRUD and then maybe some other methods like GetUserByEmail() etc.

+1  A: 

Don't use the repository pattern - use the UnitOfWork pattern instead, and pass defined query ICriteria to the ISession. Essentially the Repo pattern is wrapping something that doesn't need to be wrapped with NH.

see http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx for more info

mcintyre321
I think its misleading to imply that The unit of work and repository patterns are interchangeable as they solve different problems. I'm familiar with that post from Ayende and while I do think there is certainly some truth to it, please remember it is just an opinion, and should not be presented as fact.
Paul Batum
ight, but if you are learning NH, starting off with the Repository pattern (with flushing on every call to repo.Update()) is a bad habit. Or you can end up writing some weird hybrid of Repo and UoW that looks like a Repo but still needs to be flushed, or miss out on the greatness that is the disconnected UoW. It sounds to me like homestead has picked up a few tutorials, is making his first steps, and going down slightly wrong path for what he needs, and what is the best way to learn NH.
mcintyre321
But yeah, you're right, I made it sound like a blanket statement. the Repo pattern is useful in the right circumstances. I should have said "IMO in this case the Repo pattern is wrapping something..."
mcintyre321
Flushing on every call to your repo is a bad idea. This is why I said the two patterns solve different problems. The repositories serve as an architectural seam that makes it clear where and how your application is retrieving and inserting entities, while the ISession is your unit of work that does change tracking. IMHO you should take another look at the repository pattern, such as the one used in S#arp Architecture - because the picture you have of it (with flushing handled by the repository) is a very poor implementation.
Paul Batum
The Repository pattern, as I understand it, lets you treat a data store as if it is an in memory list of objects (from martinfowler.com/eaaCatalog/repository.html/… ". Objects can be added to and removed from the Repository, as they can from a simple collection of objects"). A simple collection of objects, if accessed from another session, will have the changes reflected immediately, so the Repo should flush. Again this is just my interpretation of the definition of Repository as per Fowler/DDD book, but neither of them mention flushing. IMO Repo needing flush != standard Repository.
mcintyre321
Again this is just my interpretation of the definition of Repository as per Fowler/DDD book, but neither of them mention flushing. IMO Repo needing flush != standard Repository. Also, that kind of repository can't be used to transparently switch to a web service or similar thing that doesn't take part in the UoW.
mcintyre321
A: 

Perhaps you misheard or someone mispoke - the Repository pattern is supposed to expose collection like behavior, not operate on collections. Just like you can add, remove and search for items in a collection, your repository offers save, delete and search operations that work against your database.

I suggest you download the code for S#arp Architecture. It includes a repository implementation that you can reuse quite easily. If you don't want to take the dependency, at the very least you can spend some time studying their implementation to give you a better idea of how to approach it yourself.

Paul Batum