Объединение всех элементов
Если бы вы хорошенько рассмотрели код с этой точки зрения, то вы бы заметили, что у нас нет стандартного способа создания экземпляра NHibernate репозитория IVisitorRepository
, который располагался бы в проекте Infrastructure. Наш UI-проект совсем не ссылается на проект Infrastructure. В данном разделе будет рассматриваться процесс соединения этих разъединенных фрагментов.
Первый фрагмент находится в файле Web.config. Внутри узла httpModules мы зарегистрировали дополнительный модуль:
<add name="StartupModule"
type="Infrastructure.NHibernateModule, Infrastructure, Version=1.0.0.0, Culture=neutral"/>
Данный модуль начинает процесс создания фабрики сессий. Он также управляет событиями BeginRequest
и EndRequest
, и создает, и разрушает NHibernate сессии для каждого веб-запроса.
Следующий листинг демонстрирует код для NHibernateModule.cs
, который расположен в проекте Infrastructure
.
Листинг 15-14: NHibernateModule
, который запускает NHibernate
using System;
using System.Web;
namespace Infrastructure
{
public class NHibernateModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += ContextBeginRequest;
}
private void ContextBeginRequest(object sender, EventArgs e)
{
DataConfig.EnsureStartup();
}
public void Dispose()
{
}
}
}
Строка 13: Убеждается в том, что конфигурация NHibernate запущена
Класс DataConfig
(показанный ранее в листинге 15-7) ответственен за создание экземпляров ISession
. Теперь, когда у нас есть фабрика сессий и сессия, наше приложение может вызвать NHibernate и взаимодействовать с базой данных.
Помимо инициализации NHibernate у нас есть инициализация VisitorRepositoryFactory
. Многие приложения используют средства IoC, которые предоставляют эти фабрики автоматически, но поскольку в данном примере не используется IoC-контейнер, нам пришлось предоставить эту логику запуска явно. Есть несколько способов выполнения этого; например, мы могли бы объявить интерфейс для фабрики и всегда держать под рукой реализацию. Воспользуйтесь своим мнением при выборе метода. Важно, что ни проект Core, ни UI-проект не должны ссылаться на проект Infrastructure или библиотеки, которые являются инфраструктурными по своей сути. Мы держали NHibernate совершенно в стороне с тем, чтобы остальная часть приложения не заботилась о том, как осуществляется процесс доступа к данным.
Необходим один окончательный шаг перед тем, как мы сможем запустить это приложение в Visual Studio при помощи Ctrl-F5. Файл Web.config ссылается на класс проекта Infrastructure, но поскольку ссылка отсутствует, комплект Infrastructure должен быть расположен в папке bin веб-сайта. Мы могли бы явно копировать его каждый раз во время компиляции, но это было бы утомительно. Решение проблемы – заставить Visual Studio копировать его каждый раз, когда он компилируется, путем добавления строк в файл Infrastructure.csproj в следующем листинге в виде postbuild
события.
Листинг 15-5: Postbuild
событие, которое копирует комплекты и config-файлы
xcopy /y ".\*.dll" "..\..\..\UI\bin\"
xcopy /y ".\*.dll" "..\..\..\IntegrationTests\bin\$(ConfigurationName)"
xcopy /y ".\log4net.config" "..\..\..\UI\"
xcopy /y ".\hibernate.cfg.xml" "..\..\..\UI\bin\"
Путем задания четырех команд, продемонстрированных в листинге, мы сконфигурировали проект Infrastructure для того, чтобы копировать два важных конфигурационных файла, а также необходимые бинарные файлы в папку bin UI-проекта и в тестовую папку. Будет копироваться не только комплект Infrastructure, но также будут копироваться и NHibernate комплекты. Это убеждает вас в том, что при запуске UI-проекта из Visual Studio вы будете приветствоваться запуском приложения, которое сохраняет и отображает посетителей, как это продемонстрировано ни рисунке 15-9.
Рисунок 15-9: Приложение работает так, как и ожидалось, после соединения элементов вместе.

Благодаря этому postbuild
шагу приложение обладает всеми необходимыми комплектами и конфигурационными файлами. Это сокращает усилия копирования этих файлов вручную, и является всего лишь одним из видов необходимой автоматизации, когда вы искренне обязуетесь разъединить ваши приложения.