Шаблон ServiceStack и NHibernate Unit Of Work

Как можно короче длинная история ...

У меня есть существующее приложение, в которое я пытаюсь включить ServiceStack для создания нашего нового API. Это приложение в настоящее время является приложением MVC3 и использует шаблон UnitOfWork с использованием внедрения атрибутов на маршрутах MVC для создания / завершения транзакции, к которой применяется атрибут.

Попытка сделать что-то подобное с помощью ServiceStack

В этой сущности показаны соответствующие параметры конфигурации ServiceStack. Что мне интересно, так это глобальные фильтры запросов / ответов - они создадут новую единицу работы для каждого запроса и закроют ее перед отправкой ответа клиенту (там есть проверка, поэтому, если возникает ошибка, запись в db, мы возвращаем клиенту соответствующий ответ, а не ложное сообщение "успех")

Мои вопросы:

  1. Это хорошая идея или нет, или есть лучший способ сделать это с помощью ServiceStack.
  2. На сайте MVC мы создаем новую единицу работы только для действия, которое будет добавлять / обновлять / удалять данные - следует ли нам делать что-то подобное здесь или нормально создавать транзакцию только для извлечения данных?

person Robin    schedule 10.01.2013    source источник


Ответы (2)


Как упоминалось в вики-сайте IOC от ServiceStack, Funq IOC регистрирует зависимости как синглтон по умолчанию. Итак, чтобы зарегистрировать его с помощью RequestScope, вам нужно указать его, как здесь:

container.RegisterAutoWiredAs<NHibernateUnitOfWork, IUnitOfWork()
    .ReusedWithin(ReuseScope.Request);

Хотя это вряд ли то, что вы хотите, поскольку он регистрируется как синглтон, то есть один и тот же экземпляр, возвращаемый для каждого запроса:

container.Register<ISession>((c) => {
    var uow = (INHibernateUnitOfWork) c.Resolve<IUnitOfWork>();
    return uow.Session;
});

Вероятно, вы захотите сделать это:

    .ReusedWithin(ReuseScope.Request); //per request

    .ReusedWithin(ReuseScope.None); //Executed each time its injected

Использование RequestScope также работает для глобальных фильтров запросов / ответов, которые получат тот же экземпляр, что и в Сервисе.

person mythz    schedule 11.01.2013
comment
Спасибо! Думаю, я слышу, что умею создавать / фиксировать UOW в фильтрах запроса / ответа. Мой NHibernateUnitOfWork - это синглтон, который использует сеанс (injectedd), так что пока сеанс настроен для определения области запроса (это так), единица работы будет через прокси, но я думаю, не повредит добавить повторно используемый внутри ( запрос). Еще раз спасибо! - person Robin; 11.01.2013

1) Независимо от того, используете ли вы ServiceStack, MVC, WCF, Nancy или любую другую веб-платформу, наиболее распространенным методом является шаблон сеанса на запрос. В веб-терминах это означает создание новой единицы работы в начале запроса и удаление единицы работы в конце запроса. Почти все веб-фреймворки имеют ловушки для этих событий.

Ресурсы:

2) Вы всегда должны взаимодействовать с NHibernate в рамках транзакции.

Пожалуйста, прочтите любое из следующих объяснений:

Обратите внимание, что при переключении на использование транзакций с чтением обязательно учитывайте поведение NULL: http://www.zvolkov.com/clog/2009/07/09/why-nhibernate-updates-db-on-commit-of-read-only-transaction/#comments

person Randy Burden    schedule 10.01.2013
comment
Спасибо, я знаю о преимуществах шаблона Unit-Of-Work и Session Per Request с NHibernate, у меня это настроено в моем GIST, с которым я связался. Мой вопрос больше касался того, был ли способ запуска и фиксации транзакции в запросе подходящим или нет (с использованием глобальных фильтров запроса / ответа). Я не вижу никаких проблем, так как у меня есть сессия, привязанная к запросу, но я не был уверен в каких-либо компромиссах, которые могут произойти ... - person Robin; 11.01.2013