Я думал, что у меня возникнет этот вопрос, пока я сам нашел решение.
После создания основной части приложения у меня есть требование в последнюю минуту поддержать чтение / запись в дополнительную базу данных (всего 2, других не известно). Я построил приложение, используя NHibernate, и Autofac поставлял компоненты DI / IoC. Кстати, это находится в приложении ASP.NET MVC 2.
У меня есть общий класс репозитория, который принимает сеанс NHibernate. Теоретически я могу продолжать использовать этот общий репозиторий (IRepository<>
) для второй базы данных, если сеанс, который ему передается, порождается из соответствующего SessionFactory, верно?
Хорошо, когда приложение запускается, Autofac делает свое дело. Что касается Session и SessionFactory, у меня есть модуль, который заявляет:
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
.InstancePerMatchingLifetimeScope(WebLifetime.Request)
.OnActivated(e =>
{
e.Context.Resolve<TransactionManager>().CurrentTransaction = ((ISession)e.Instance).BeginTransaction();
});
builder.Register(c => ConfigureNHibernate())
.SingleInstance();
где ConfigureNHibernate (), который возвращает базовый SessionFactory, выглядит следующим образом:
private ISessionFactory ConfigureNHibernate()
{
Configuration cfg = new Configuration().Configure();
cfg.AddAssembly(typeof(Entity).Assembly);
return cfg.Configure().BuildSessionFactory();
}
В настоящее время это ограничено только одной базой данных. В любом другом сценарии NHib я, вероятно, помещал бы экземпляры отдельных SessionFactories в хеш и извлекал их по мере необходимости. Я не хочу переделывать всю эту архитектуру, так как мы довольно близки к основной версии. Итак, я предполагаю, что мне нужно изменить хотя бы описанные выше методы, чтобы я мог независимо настроить две SessionFactories. Моя серая область - как я буду указывать правильную фабрику, которая будет использоваться с конкретным репозиторием (или, по крайней мере, для сущностей, специфичных для этой второй базы данных).
Кто-нибудь имеет опыт работы с этим сценарием при использовании контейнера IoC и NHibernate таким образом?
EDIT
Я заглушил метод GetSessionFactory, который принимает путь к файлу конфигурации, проверяет наличие соответствующего SessionFactory в HttpRuntime.Cache, создает новый экземпляр, если он еще не существует, и возвращает этот SessionFactory. Теперь мне все еще нужно выяснить, как сообщить Autofac, как и когда указывать соответствующий путь конфигурации. Новый метод выглядит так (заимствовано из поста Билли за 2006 год здесь ):
private ISessionFactory GetSessionFactory(string sessionFactoryConfigPath)
{
Configuration cfg = null;
var sessionFactory = (ISessionFactory)HttpRuntime.Cache.Get(sessionFactoryConfigPath);
if (sessionFactory == null)
{
if (!File.Exists(sessionFactoryConfigPath))
throw new FileNotFoundException("The nhibernate configuration file at '" + sessionFactoryConfigPath + "' could not be found.");
cfg = new Configuration().Configure(sessionFactoryConfigPath);
sessionFactory = cfg.BuildSessionFactory();
if (sessionFactory == null)
{
throw new Exception("cfg.BuildSessionFactory() returned null.");
}
HttpRuntime.Cache.Add(sessionFactoryConfigPath, sessionFactory, null, DateTime.Now.AddDays(7), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);
}
return sessionFactory;
}