Свободный шаблон NHibernate как для IHttpModule, так и для консольных приложений

#c# #asp.net-mvc #design-patterns #fluent-nhibernate

#c# #asp.net-mvc #шаблоны проектирования #свободный-nhibernate

Вопрос:

В настоящее время у меня есть веб-приложение C # MVC 2, использующее Fluent NHibernate ( LINQ) в шаблоне репозитория, и я использую Ninject для обработки требования конструктора контроллера MVC, чтобы оно было передано в репозиторий.

Мой код Fluent NHibernate в настоящее время подключен к IHttpModule, поэтому сеанс может быть открыт и закрыт с помощью веб-запроса.

Это отлично работает, пока я не попытаюсь подключить свою модель домена к консольному приложению.

Во-первых, я решил перенести логику моей базы данных в мою модель домена. Я предполагаю, что это плохое поведение, но я здесь прошу помощи в разработке кода, поэтому, пожалуйста, не стесняйтесь вносить предложения. Я хотел сделать это, потому что я хочу написать консольное приложение веб-приложение для этой модели домена, не заботясь о том, где и как хранятся данные. Возможно, мне следует создать отдельный «инфраструктурный» проект, который использует модель предметной области для выполнения конкретной реализации?

Возвращаясь к вопросу… Я столкнулся с проблемой, когда, похоже, функция getCurrentSession () от Fluent NHibernate предполагает, что вы используете веб-интерфейс — происходит сбой, и я получаю обратный путь к некоторому NH-коду, в котором упоминается веб-сессия.

Для справки, код находится здесь:https://github.com/cthielen/RightsManagement .

Приношу свои извинения за то, что не был слишком конкретным; Я ищу рекомендации по дизайну кода, чтобы наилучшим образом обрабатывать FNH Linq в шаблоне репозитория, который хорошо работает как с Веб, так и с консольным приложением — и отдельно спрашиваю, должно ли мое подключение к базе данных (т. Е. NH logic) быть в проекте домена или нет.

Ответ №1:

Это хороший вопрос. На этот вопрос можно ответить множеством разных способов, но каждый ответ будет зависеть от того, какой опыт у вас есть с различными существующими подходами. Например, знакомы ли вы с TDD? Внедрение зависимостей? Контейнеры IoC? И так далее.

Лучший совет, который я могу дать на этом этапе, — очистить все ваши существующие классы, чтобы они не зависели от контекста. Одним из примеров этого может быть изменение ваших классов репозитория таким образом, чтобы они принимали объект ISession в качестве аргумента конструктора вместо зависимости от того, что кажется экземпляром singleton, который существует только в том случае, если вы находитесь в контексте HTTP. Это позволило бы вам реорганизовать логику создания сеанса на более высокий уровень за пределами логики вашего домена.

 public class PeopleRepository {
    public PeopleRepository(ISession session) {
        // store session
    }
}
  

В моем случае я бы использовал контейнер IoC для внедрения зависимости сеанса. Я могу использовать этот контейнер из приложений любого типа, будь то веб-приложение, использующее шаблон «сеанс за запрос» или консольное приложение.

Вам нужно будет проделать некоторую работу, чтобы заставить NHibernate хорошо работать в обоих приложениях. Задача состоит в том, чтобы максимально минимизировать эту работу.

Я рад предоставить дополнительные рекомендации. Дайте мне знать.

Ответ №2:

Я часто использую объект session, чтобы указать, что я собираюсь с чем-то работать (это не реализация Unit Of Work, поскольку я не сохраняю всю работу до определенного момента)

 using (var session = SessionFactory.Create())
{
   // do all work here
}
  

Это работает, поскольку даже консольные приложения имеют отправную точку, в которой может быть инициирован сеанс (например, когда пользователь написал команду в консоли).

Фабрика сеансов имеет SessionCreated и SessionDestroyed событие, которые могут быть подключены к чему угодно, в нашем случае к фабрике сеансов nhibernate.

Это хороший абстрактный способ получить поддержку подключения к базе данных или чего-либо еще без использования жестких зависимостей