Мы поступаем немного иначе, чем Бигглсби, и я не говорю, что он неправ, или что наш идеален.
В global.asax, который мы имеем при запуске приложения, имеем:
...
protected void Application_Start() {
ISessionFactory sf =
DataRepository
.CreateSessionFactory(
ConfigurationManager
.ConnectionStrings["conn_string"]
.ConnectionString
);
//use windsor castle to inject the session
ControllerBuilder
.Current
.SetControllerFactory(new WindsorControllerFactory(sf));
}
...
Наш DataRepository у нас есть:
ПРИМЕЧАНИЕ: (это не репозиторий - моя ошибка проектирования: плохое имя - он больше похож на ваш NHibernateHelper, я думаю, это скорее своего рода оболочка конфигурации NH какого-то рода ...)
....
public static ISessionFactory CreateSessionFactory(string connectionString) {
if (_sessionFactory == null){
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration ...
...
//custom configuration settings
...
cfg.SetListener(ListenerType.PostInsert, new AuditListener());
})
.BuildSessionFactory();
}
return _sessionFactory;
}
....
С фабрикой сессий вы не хотите генерировать / создавать ее при каждом запросе. DataRepository действует как одноэлементный, гарантируя, что фабрика сеансов создается только один раз, и это при запуске приложения. В нашем базовом контроллере мы внедряем либо сессию, либо сессионную фабрику в наши контроллеры (некоторые контроллеры не требуют подключения к базе данных, поэтому они наследуются от базового контроллера «без базы данных»), используя WindosrCastle. Наш WindsorControllerFactory у нас есть:
...
//constructor
public WindsorControllerFactory(ISessessionFactory) {
Initialize();
// Set the session Factory for NHibernate
_container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(
() => sessionFactory)
.LifeStyle
.Transient
);
}
private void Initialize() {
_container = new WindsorContainer(
new XmlInterpreter(
new ConfigResource("castle")
)
);
_container.AddFacility<FactorySupportFacility>();
// Also register all the controller types as transient
var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (var t in controllerTypes) {
_container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
}
}
....
При такой настройке каждый запрос генерирует сеанс NHibernate, а благодаря нашему дизайну у нас также есть контроллеры, которые не генерируют сеансы. И это в настоящее время, как это работает для нас.
Могу ли я также сказать, что я нашел NHProf очень полезным при попытке настроить или отладить имеющуюся у нас проблему.