So at the moment I have such a repository implementation:
public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
private ISession session;
public Repository(ISession session)
{
this.session = session;
}
public T Get(Guid id)
{
return this.session.Get<T>(id);
}
public IQueryable<T> Get(Expression<Func<T, Boolean>> predicate)
{
return this.session.Query<T>().Where(predicate);
}
public IQueryable<T> Get()
{
return this.session.Query<T>();
}
public T Load(Guid id)
{
return this.session.Load<T>(id);
}
public void Add(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Save(entity);
transaction.Commit();
}
}
public void Remove(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Delete(entity);
transaction.Commit();
}
}
public void Remove(Guid id)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Delete(this.session.Load<T>(id));
transaction.Commit();
}
}
public void Update(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(entity);
transaction.Commit();
}
}
public void Update(Guid id)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(this.session.Load<T>(id));
transaction.Commit();
}
}
}
Then I use Ninject
module like this.
public class DataAccessModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<ISessionFactory>()
.ToMethod(c => new Configuration().Configure().BuildSessionFactory())
.InSingletonScope();
this.Bind<ISession>()
.ToMethod(ctx => ctx.Kernel.TryGet<ISessionFactory>().OpenSession())
.InRequestScope();
this.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
}
}
Schema export and update are called like a tests:
[TestFixture]
public class SchemaManipulations
{
[Test]
[Ignore]
public void CreateDatabaseSchema()
{
new SchemaExport(new Configuration().Configure()).Create(false, true);
}
[Test]
[Ignore]
public void UpdateDatabaseSchema()
{
new SchemaUpdate(new Configuration().Configure()).Execute(false, true);
}
}
I keep 'clean' my domain layer: validation logic is implemented with FluentValidation
, it has no knowledge of NHibernate
neither of anything else.
And that seemed perfect to me.. until I wondered how do I implement version concurrency. I choose to use optimistic-locking
and as for mapping it correctly for NH
it was not a problem. And I was needed to know how do transaction handle, how do I inform user while editing locked
item?
So one more question appeared version concurrency control for a long session. NHibernate. ASP.NET MVC where it was said that exposing transaction on Repository
is not recommended.
QUESTION ITSELF
I have already heard about SharpArchitecture
and about UOW
. And that's quite enough.
But I'm interested in issues provided with my solution of data access strategy: what errors/malfunctions will I face using it like that?
Also would it be a solution to use the proposed by Kaleb Pederson
NHibernate, transactions and TransactionScope approach?
Thanks!