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.