Вложенные вызовы NHibernateFacility SessionManager.OpenSession
Я чувствую, что я что-то неправильно понимаю. Посмотрите на следующий код. я имею DefaultSessionLifeStyleOption.SessionPerTransaction
установлен, но мои сеансы имеют разные идентификаторы сеансов, даже если они находятся в одной транзакции. Я ожидал одну сессию, но есть две.
Что я делаю не так, и как мне сделать так, как я хочу? Я должен вместо этого ввести ISession
в Program
и мои методы используют эту сессию? Но тогда я не потеряю преимущества SessionManager
с AutoTxFacility
?
using Castle.Facilities.AutoTx;
using Castle.Facilities.FactorySupport;
using Castle.Facilities.NHibernate;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Transactions;
using Castle.Windsor;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using System;
using System.Transactions;
namespace Sandbox
{
public class DBInstaller : INHibernateInstaller
{
public FluentConfiguration BuildFluent()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString("Server=localhost;Integrated security=true;"));
}
public Maybe<IInterceptor> Interceptor { get { return Maybe.None<IInterceptor>(); } }
public bool IsDefault { get { return true; } }
public void Registered(ISessionFactory factory) { }
public string SessionFactoryKey { get { return "foo"; } }
}
public class Program
{
public ISessionManager SessionMan { get; set; }
static void Main(string[] args)
{
IWindsorContainer container = new WindsorContainer();
container
.Register(Component.For<INHibernateInstaller>().ImplementedBy<DBInstaller>())
.AddFacility<FactorySupportFacility>() // used by AutoTxFacility, we dont use it directly at this time
.AddFacility<TypedFactoryFacility>() // used by AutoTxFacility, we're probably using it somewhere
.AddFacility<AutoTxFacility>() // automatically manages DB transactions for us, if we want.
.AddFacility<NHibernateFacility>(x => x.DefaultLifeStyle = DefaultSessionLifeStyleOption.SessionPerTransaction)
.Register(
Component.For<Program>().ImplementedBy<Program>().LifestyleTransient());
var p = container.Resolve<Program>();
p.Foo();
}
[Transaction(TransactionScopeOption.Required)]
public virtual void Foo()
{
using (var session = SessionMan.OpenSession())
{
Console.WriteLine("Foo: {0}", ((NHibernate.Impl.SessionImpl)session).SessionId);
Bar();
}
}
public virtual void Bar()
{
using (var session = SessionMan.OpenSession())
{
Console.WriteLine("Bar: {0}", ((NHibernate.Impl.SessionImpl)session).SessionId);
}
}
}
}