Use of castle windsor means ISession sometimes disposed more than once
All my repository interfaces (i.e. implemented by classes for persisting entities to the database) have a dependency on an interface called IUnitOfWork
. The repository classes and the IUnitOfWork
are handled by Castle Windsor and have a lifestyle of PerWebRequest
.
The Repository<T>
implementation (which is extended by all repositories) looks like this:
public abstract class Repository<T> where T : Entity
{
protected IUnitOfWork _unitOfWork;
internal Repository(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public T Load(int id)
{
T t;
t = _unitOfWork.Load<T>(id);
return t;
}
public virtual void Save(T t)
{
_unitOfWork.Save(t);
}
public virtual void Delete(T t)
{
_unitOfWork.Delete(t);
}
public IQueryable<T> All
{
get { return _unitOfWork.GetList<T>(); }
}
}
The class which implements IUnitOfWork
uses NHibernate (it contains an ISession
) and has a Dispose
method like this:
public void Dispose()
{
_session.Flush();
_session.Dispose();
}
Thus, the saving of an entity follows the following steps:
- Repository retrieved from DI container (with
IUnitOfWork
injected in) - Entity loaded through repository's
Load
method - Entity modified
- Entity saved through repository's
Save
method - Repository and
IUnitOfWork
disposed by DI container at end of web request - changes flushed to 开发者_StackOverflowdatabase
My problem is that I am occasionally getting the 'Session is closed! Object name: 'ISession' error from NHibernate.
So far as I can see, the only place the ISession
is disposed is when the IUnitOfWork
's Dispose()
method is called, which is only called by the DI container.
Can anyone think of any other reason I could be getting this error?
That probably happens when you have an exception somewhere, or you're trying to call Dispose
yourself in the code somewhere.
Windsor guarantees that the code will be only executed once.
As a sidenote - why do you need the IUnitOfWork
? It doesn't add any value.
精彩评论