7

Я поднял этот вопрос раньше, но я все еще изо всех сил пытаюсь найти пример, в котором я могу раздобыть голову (пожалуйста, не просто скажите мне посмотреть проект архитектуры S # arp Architecture, по крайней мере, на некоторые направления).Как я могу реализовать NHibernate-сеанс для каждого запроса без зависимости от NHibernate?

До сих пор я достиг почти незнания невежества в своем веб-проекте. Мои хранилища классов (в моем проекте данных) принимают ISession в конструкторе:

public class ProductRepository : IProductRepository 
{ 
    private ISession _session; 
    public ProductRepository(ISession session) { 
     _session = session; 
    } 

В моей global.asax я разоблачить текущую сессию и творю и утилизации сессии BeginRequest и EndRequest (это где у меня есть зависимость от NHibernate):

public static ISessionFactory SessionFactory = CreateSessionFactory(); 

    private static ISessionFactory CreateSessionFactory() { 
     return new Configuration() 
      .Configure() 
      .BuildSessionFactory(); 
    } 

    protected MvcApplication() { 
     BeginRequest += delegate { 
      CurrentSessionContext.Bind(SessionFactory.OpenSession()); 
     }; 
     EndRequest += delegate { 
      CurrentSessionContext.Unbind(SessionFactory).Dispose(); 
     }; 
    } 

и, наконец, мой StructureMap реестр:

public AppRegistry() { 
     For<ISession>().TheDefault 
      .Is.ConstructedBy(x => MvcApplication.SessionFactory.GetCurrentSession()); 

     For<IProductRepository>().Use<ProductRepository>(); 
    } 

Казалось бы, мне нужна мои собственные общие реализации ISession и ISessionFactory, который я могу использовать в своем веб-проекте и вводить в свои репозитории?

Так просто пояснить - я использую NHibernate в своем слое репозитория и хочу использовать запрос на сеанс (http). Поэтому я ввожу ISession в мои конструкторы репозитория (используя структуру структуры). В настоящее время для создания и размещения сеансов в каждом запросе мне нужно ссылаться на NHibernate из моего веб-проекта. Это зависимость, которую я хотел бы удалить.

Спасибо, Бен

+6

NHibernate согласно мне не плохой зависимости. –

+0

Мой веб-проект ведет переговоры с хранилищем, а NHibernate - зависимость репозитория. Если бы не тот факт, что мне нужен сеанс для запроса, я мог бы просто открыть свои сеансы внутри слоя репозитория. Тем не менее, мне нужен сеанс для запроса, но я не хочу, чтобы мой веб-проект был привязан к NHibernate. –

+2

Will Marcouiller: Это все еще зависимость. Зависимость - это зависимость. Что, если Бен захотел перенести свое приложение на CouchDB или MongoDB или использовать базу данных объектов в памяти? –

ответ

3

Почему вы не создать IHttpModule и выполнить свое создание и утилизации там (вероятно, в Begin_Request и end_request события), но поставить IHttpModule внутри проекта, который имеет свой NHibernate зависимость , например.

namespace MyWebApp.Repository.NHibernateImpl 
{ 
    public class NHibernateModule : IHttpModule 
    { 
     public void Init(HttpApplication context) 
     { 
      context.BeginRequest += new EventHandler(Context_BeginRequest); 
      context.EndRequest += new EventHandler(Context_EndRequest); 
     } 

     private void Context_BeginRequest(object sender, EventArgs e) 
     { 
      // Create your ISession 
     } 

     private void Context_EndRequest(object sender, EventArgs e) 
     { 
      // Close/Dispose your ISession 
     } 

     public void Dispose() 
     { 
      // Perhaps dispose of your ISessionFactory here 
     } 
    } 
} 

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

+0

Это маршрут, по которому я начал снижаться, но, как и вы, мне интересно, если там является лучшим (более дружественным к DI) способом сделать это. –

+0

@Ben - Но это не плохая плохая зависимость, так как вам не придется ссылаться на эти объекты, не ссылаясь на нее в своем веб-проекте. Все, что вам нужно сделать, это настроить это в вашем web.config. В чем проблема?Если вы настраиваете свой контейнер DI через XML, вам также придется вводить его. – jfneis

+0

@jfneis - у вас есть полный пример использования HttpModule - меня особенно интересует, как я все еще могу добавить свою сессию в репозитории и обрабатывать транзакции по-разному. –

0

Спасибо за помощь всем. Немного больше исследований привело меня к проекту NHibernate Burrow.

Из проекта FAQ (http://nhforge.org/wikis/burrow/faq.aspx):

Барроу является легкий вес промежуточного слоя разработан для поддержки .Net-приложений с использованием NHibernate (возможно, также упоминается как NH в этой статье) в рамках ОРМ. Использование Asp.net с NHibernate может быть проблемой из-за того, что NHibernate - среда с сохранением состояния, в то время как Asp.net - это система без гражданства. Burrow может помочь в разрешении этого конфликта, предоставляя расширенное и интеллектуальное управление сеансом/транзакциями и другие облегчает.

Мне пришлось перепрыгнуть через несколько обручей, чтобы они работали в моем проекте. Поскольку в текущем выпуске используется старая версия NHibernate, мне пришлось загрузить latest source с внешней стороны, открыть в VS, добавить ссылки на последнюю версию NHibernate и перекомпилировать (к счастью, никаких ошибок).

Я проверил NHibernate Burrow несколькими способами.

1) Продолжить инъекционные ISession в моих репозиториях

Чтобы сделать это, мне пришлось добавить ссылки на NHibernate, NHibernate.Burrow и NHibernate.Burrow.WebUtil для моего проекта MVC.

В web.config я должен был установить Барроу (см http://nhforge.org/wikis/burrow/get-started.aspx), а затем в моем StructureMap реестре добавить следующее:

 For<ISession>() 
      .TheDefault.Is 
      .ConstructedBy(x => new NHibernate.Burrow.BurrowFramework().GetSession());   

Мне нравится этот подход, поскольку это означает, что мои репозиториев (или контроллеры) не являются в сочетании с Берроу. Мне не очень нравится тот факт, что мне приходится ссылаться на эти три сборки в моем веб-проекте, но по крайней мере я теряю код для управления сеансом - все это обрабатывает Burrow.

2) Второй подход должен были бы установить ISession в моем хранилище конструкторов так:

public ProductRepository() : 
     this(new BurrowFramework().GetSession()) { } 

    public ProductRepository(ISession session) { 
     _session = session; 
    } 

я все еще могу переопределить ISession делаю мои хранилища проверяемыми. У меня тогда есть прямая зависимость от Берроу, но, возможно, это не так плохо?

С плюсом стороны, единственная сборка, которую мне нужно сделать ссылкой из моего веб-проекта, это NHibernate.Burrow.WebUtils.

Заинтересованы в том, чтобы узнать, какой из двух человек пойдет и почему.

2

На мой взгляд, вы должны принять ISession и работать с ним напрямую. Проблема со многими реализациями для каждого запроса заключается в том, что они задерживают выполнение изменений базы данных до конца HTTP-запроса. Если транзакция не удалась, все, что вы можете сделать в этот момент, - это прямой пользователь на общей странице ошибок. Гораздо лучше управлять транзакцией на странице, чтобы вы могли лучше поймать и обработать ошибки. Если вы берете этот маршрут, вам необходимо получить доступ к ISession или обертке для управления транзакцией.

Кроме того, в какой-то момент ваше приложение, вероятно, должно будет использовать свойства или методы, предоставляемые ISession, особенно Merge and Load.

+0

Что бы вы предложили вместо шаблона запроса на запрос? Или вы предлагаете не открывать сеанс и транзакцию при попрошайничестве, а затем закрывать их в конце запроса? – RandomWebGuy

Смежные вопросы