My repositories all take ISession in the constructor:
protected Repository(ISession session)
{
this.session = session;
}
private readonly ISession sessi
This question & answers might help you.
One way to go - steal nhibernate session management from "S#arp Architecture". Works great.
You should register ISession using a factory method.
Another options (not always the best, but easy to use) is to:
Implement ISession and ISessionFactory interfaces (SessionProxy and SessionFactoryProxy).
public class SessionAggregator : ISession {
protected ISession session;
public SessionAggregator(ISessionFactory theFactory) {
if (theFactory == null)
throw new ArgumentNullException("theFactory", "theFactory is null.");
Initialise(theFactory);
}
protected virtual void Initialise(ISessionFactory factory) {
session = factory.OpenSession();
}
// the ISession implementation - proxy calls to the underlying session
}
public class SessionFactoryAggregator : ISessionFactory {
protected static ISessionFactory factory;
private static locker = new object();
public SessionFactoryAggregator() {
if (factory == null) {
lock(locker) {
if (factory == null)
factory = BuildFactory();
}
}
}
// Implement the ISessionFactory and proxy calls to the factory
}
This way you can just register ISession (implemented by SessionAggregator) and ISessionFactory (SessionFactoryAggreagator) and any DI framework will resolve ISession easily.
This is good if your DI does not support factory method (I don't know if Structure Map does).
I have added these implementation to my Commons assembly so I should not reimplement it every time.
EDIT: Now, to make use of ISession in web application:
The code can look like:
// The Registry in StructureMap
ForRequestedType<ISessionFactory>()
.CacheBy(InstanceScope.Singleton)
.TheDefaultIsConcreteType<SessionFactoryAggregator>();
ForRequestedType<ISession>()
.CacheBy(InstanceScope.Hybryd)
.TheDefaultIsConcreteType<SessionAggregator>();
// Then in EndRequest call
HttpContextBuildPolicy.DisposeAndClearAll()