FluentNHibernate Unit Of Work / Repository Design Pattern Questions

Posted by Echiban on Stack Overflow See other posts from Stack Overflow or by Echiban
Published on 2010-04-02T23:39:35Z Indexed on 2010/04/02 23:43 UTC
Read the original article Hit count: 1031

Hi all,

I think I am at a impasse here. I have an application I built from scratch using FluentNHibernate (ORM) / SQLite (file db). I have decided to implement the Unit of Work and Repository Design pattern. I am at a point where I need to think about the end game, which will start as a WPF windows app (using MVVM) and eventually implement web services / ASP.Net as UI.

Now I already created domain objects (entities) for ORM. And now I don't know how should I use it outside of ORM. Questions about it include:

  • Should I use ORM entity objects directly as models in MVVM? If yes, do I put business logic (such as certain values must be positive and be greater than another Property) in those entity objects? It is certainly the simpler approach, and one I am leaning right now. However, will there be gotchas that would trash this plan?
  • If the answer above is no, do I then create a new set of classes to implement business logic and use those as Models in MVVM? How would I deal with the transition between model objects and entity objects? I guess a type converter implementation would work well here.

Now I followed this well written article to implement the Unit Of Work pattern. However, due to the fact that I am using FluentNHibernate instead of NHibernate, I had to bastardize the implementation of UnitOfWorkFactory. Here's my implementation:

using System;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;

namespace ELau.BlindsManagement.Business
{
    public class UnitOfWorkFactory : IUnitOfWorkFactory
    {
        private static readonly string DbFilename;
        private static Configuration _configuration;
        private static ISession _currentSession;
        private ISessionFactory _sessionFactory;

        static UnitOfWorkFactory()
        {
            // arbitrary default filename
            DbFilename = "defaultBlindsDb.db3";
        }

        internal UnitOfWorkFactory()
        {
        }

        #region IUnitOfWorkFactory Members

        public ISession CurrentSession
        {
            get
            {
                if (_currentSession == null)
                {
                    throw new InvalidOperationException(ExceptionStringTable.Generic_NotInUnitOfWork);
                }
                return _currentSession;
            }
            set { _currentSession = value; }
        }

        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    _sessionFactory = BuildSessionFactory();
                }

                return _sessionFactory;
            }
        }

        public Configuration Configuration
        {
            get
            {
                if (_configuration == null)
                {
                    Fluently.Configure().ExposeConfiguration(c => _configuration = c);
                }

                return _configuration;
            }
        }

        public IUnitOfWork Create()
        {
            ISession session = CreateSession();
            session.FlushMode = FlushMode.Commit;
            _currentSession = session;
            return new UnitOfWorkImplementor(this, session);
        }

        public void DisposeUnitOfWork(UnitOfWorkImplementor adapter)
        {
            CurrentSession = null;
            UnitOfWork.DisposeUnitOfWork(adapter);
        }

        #endregion

        public ISession CreateSession()
        {
            return SessionFactory.OpenSession();
        }

        public IStatelessSession CreateStatelessSession()
        {
            return SessionFactory.OpenStatelessSession();
        }

        private static ISessionFactory BuildSessionFactory()
        {
            ISessionFactory result = Fluently.Configure()
                .Database(
                SQLiteConfiguration.Standard
                    .UsingFile(DbFilename)
                )
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UnitOfWorkFactory>())
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();

            return result;
        }

        private static void BuildSchema(Configuration config)
        {
            // this NHibernate tool takes a configuration (with mapping info in)
            // and exports a database schema from it
            _configuration = config;
            new SchemaExport(_configuration).Create(false, true);
        }
    }
}

I know that this implementation is flawed because a few tests pass when run individually, but when all tests are run, it would fail for some unknown reason. Whoever wants to help me out with this one, given its complexity, please contact me by private message. I am willing to send some $$$ by Paypal to someone who can address the issue and provide solid explanation.

I am new to ORM, so any assistance is appreciated.

© Stack Overflow or respective owner

Related posts about nhibernate

Related posts about fluent-nhibernate