no, you are still managing the session's scope. you simply tie the
scope of the session to the request.
you would *not* have using blocks in your code
using(var s = f.opensession())
{
}
here is the code I'm using the manage session scope and transactions.
public class SessionModule : IHttpModule
{
private TransactionScope transaction;
public void Init(HttpApplication context)
{
context.BeginRequest += OpenSessions;
context.EndRequest += DisposeOfSessions;
}
private void OpenSessions(object sender, EventArgs e)
{
var options = new TransactionOptions {IsolationLevel =
IsolationLevel.ReadCommitted};
transaction = new TransactionScope
(TransactionScopeOption.Required, options);
var session = WindsorContainerAccessorUtil
.ObtainContainer()
.Resolve<ISessionFactory>()
.OpenSession();
ManagedWebSessionContext.Bind(HttpContext.Current,
session);
}
private void DisposeOfSessions(object sender, EventArgs e)
{
if (HttpContext.Current.Error == null)
transaction.Complete();
var factory = WindsorContainerAccessorUtil
.ObtainContainer()
.Resolve<ISessionFactory>();
ManagedWebSessionContext.Unbind(HttpContext.Current,
factory).Dispose();
transaction.Dispose();
}
public void Dispose()
{
}
}
then I have my controllers and/or services
public class MyController : SmartDispatchController
{
private ISession session;
public MyController(ISession session)
{
this.session = session;
}
}
and finally the facility to wire all this together
public class NhibernateFacility : AbstractFacility
{
protected override void Init()
{
var configuration = Fluently
.Configure()
.Database(MsSqlConfiguration
.MsSql2000
.ProxyFactoryFactory(typeof
(ProxyFactoryFactory).AssemblyQualifiedName)
.ConnectionString(builder =>
builder.FromConnectionStringWithKey("key")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>
())
.ExposeConfiguration(cfg => cfg
.SetProperty
(Environment.PrepareSql, true.ToString())
.SetProperty
(Environment.CurrentSessionContextClass, typeof
(ManagedWebSessionContext).AssemblyQualifiedName))
.BuildConfiguration();
var factory = configuration.BuildSessionFactory();
Kernel.AddComponentInstance<Configuration>(configuration);
Kernel.AddComponentInstance<ISessionFactory>(factory);
Kernel.Register(Component
.For<ISession>()
.LifeStyle.Is(LifestyleType.Transient)
.UsingFactoryMethod(k =>
k.Resolve<ISessionFactory>().GetCurrentSession()));
}
}
this approach also requires the FactoryFacility to use the factory
methods. You could replace the factory method with a
SubDependencyResolver.
On Nov 3, 11:58 am, Shawn Hinsey <
smhin...@gmail.com> wrote:
> So to clarify, even though I might dispose a session from the session
> manager, it will be kept alive until the end of the request by the
> infrastructure?
>
> I would have to set it up again but I am fairly certain I saw behavior
> roughly like this:
>
> MyPersistentObject po;
>
> using(var session = _sessionManager.OpenSession()
> {
> po = session.Find...
>
> }
>
> // later, in a controller
>
> po.LazyCollection
>
> throw an exception about a missing session.
>
> On Tue, Nov 3, 2009 at 2:10 AM, Tuna Toksoz <
tehl...@gmail.com> wrote:
> > in a web environment, what is done in NH Facility is that the session is
> > opened at the beginning of the http request, stored in web session. Atthe
> > end of the request, it is committer and disposed. Using this logic allows
> > you to have lazy loading working pretty easily. It comes with downsides,
> > though.
>
> > Tuna Toksöz
> > Eternal sunshine of the open source mind.
>
> >
http://devlicio.us/blogs/tuna_toksoz
> >
http://tunatoksoz.com
> >
http://twitter.com/tehlike
>