これは私があなたのために物事がうまくいくかもしれない方法です。一部の構成がうまくいかない場合に備えて、FluentNhibernateを使用します。
public interface INHibernateSessionFactoryHelper
{
ISessionFactory CreateSessionFactory();
}
public class NhibernateSessionFactoryHelper
{
private static readonly string ConnectionString =
ConfigurationManager.ConnectionStrings["SqlConnectionString"].ToString();
public static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<EntityMap>())
.Database(
MsSqlConfiguration.MsSql2008.ConnectionString(ConnectionString).AdoNetBatchSize(1000))
.Cache(
c =>
c.ProviderClass<SysCacheProvider>().UseSecondLevelCache().UseQueryCache().UseMinimalPuts())
.ExposeConfiguration(c => c.SetProperty(Environment.GenerateStatistics, "true")
.SetProperty(Environment.SessionFactoryName, "My Session Factory")
.SetProperty(Environment.CurrentSessionContextClass, "web"))
.Diagnostics(d => d.Enable().OutputToFile(@"c:\temp\diags.txt"))
.BuildSessionFactory();
}
}
次に、私のWindsorインストーラーは次のようになります
public class NHibernateInstaller:IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ISessionFactory>().Instance(NhibernateSessionFactoryHelper.CreateSessionFactory()));
container.Register(Component.For<ISessionManager>().ImplementedBy<SessionManager>().LifestylePerWebRequest());
}
}
使用しているSessionManagerのコードを省略しました。ご希望の場合はお知らせください
UPDTAE:セッションとトランザクションの管理に使用するコードは次のとおりです(インターネット上に散在しているものを見つけましたが、あまり変更しなくてもすべてうまく機能しました。ISessionManagerは前の例に従って配線され、サービスの構成者に挿入されています。
public interface ISessionManager : IDisposable
{
ISession Session { get; set; }
ISession GetSession();
}
public class SessionManager : ISessionManager
{
private readonly ISessionFactory _sessionFactory;
private TransactionScope _scope;
public SessionManager(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
#region ISessionManager Members
public ISession Session { get; set; }
public ISession GetSession()
{
if (Session == null)
{
Session = _sessionFactory.OpenSession();
if (!CurrentSessionContext.HasBind(_sessionFactory))
{
_scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions {IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted});
Session.BeginTransaction(IsolationLevel.ReadCommitted);
CurrentSessionContext.Bind(Session);
}
}
Session = _sessionFactory.GetCurrentSession();
Session.FlushMode = FlushMode.Never;
return Session;
}
public void Dispose()
{
if (CurrentSessionContext.HasBind(_sessionFactory))
{
CurrentSessionContext.Unbind(_sessionFactory);
}
try
{
Session.Transaction.Commit();
_scope.Complete();
_scope.Dispose();
Session.Flush();
}
catch (Exception)
{
if (Session.Transaction != null && Session.Transaction.IsActive)
{
Session.Transaction.Rollback();
}
throw;
}
finally
{
Session.Close();
Session.Dispose();
}
}
#endregion
}
コンストラクターの例:
private readonly ISessionManager _sessionManager;
private readonly ISession _session;
public UserService(ISessionManager sessionManager)
{
_sessionManager = sessionManager;
_session = sessionManager.GetSession();
}