I’ve got the following code wiring a NHibernate ISession in Autofac for a ASP.NET application :
builder.RegisterAdapter<ISessionFactory, ISession>(factory => factory.OpenSession())
.InstancePerHttpRequest()
.OnActivated(activatedArgs =>
{
var session = activatedArgs.Instance;
session.BeginTransaction();
})
.OnRelease(session =>
{
if (session.Transaction != null && session.Transaction.IsActive)
{
try
{
session.Transaction.Commit();
}
catch(Exception e)
{
session.Transaction.Rollback();
throw;
}
}
});
Will the session be properly disposed even with a thrown exception in the commit? Is this a correct usage of ISession together with autofac?
No- throwing in
Dispose()isn’t a good idea with Autofac. The correct disposal of other component instances isn’t guaranteed.In general it should be avoided – WCF for example has a well known and long-standing usability problem because connections throw during disposal. The basic antipattern is that
Dispose()is often called because an exception is propagating. Throwing a further exception masks the original oneEdit:
As a thought experiment – let’s say this was supported using some try/catch magic in Autofac. What happens if
OnRelease()throws for two different components? We can’t propagate both exceptions. Further – once the exception has bubbled out of Autofac, who can catch it? All of the components servicing the request have now been released.Hope this helps, Nick.