Может ли исключение во время OnRelease вызвать неправильную утилизацию компонента? - PullRequest
3 голосов
/ 27 февраля 2011

У меня есть следующий код для подключения NHibernate ISession в Autofac для приложения ASP.NET:

builder.RegisterAdapter<ISessionFactory, ISession>(factory => factory.OpenSession())
    .InstancePerHttpRequest()
    .OnActivated(activatedArgs =>
                 {
                     var session = activatedArgs.Instance;
                     session.BeginTransaction();
                 })
    .OnRelease(session =>
               {
                   if (session.Transaction != null && session.Transaction.IsActive)
                   {
                       try
                       {
                           session.Transaction.Commit();
                       }
                       catch(Exception e)
                       {
                           session.Transaction.Rollback();
                           throw;
                       }
                   }
               });

Будет ли сеанс должным образом удален даже при исключении в коммите? Это правильное использование ISession вместе с autofac?

Ответы [ 2 ]

2 голосов
/ 28 февраля 2011

Нет - добавление Dispose() не очень хорошая идея с Autofac.Правильная утилизация других экземпляров компонентов не гарантируется.

В целом этого следует избегать - например, WCF имеет хорошо известную и давнюю проблему с удобством использования, поскольку соединения выбрасываются во время утилизации.Основным антипаттерном является то, что Dispose() часто вызывается, потому что распространяется исключение.Бросив еще одно исключение, маскируем исходное

Редактировать:

В качестве мысленного эксперимента - допустим, это было поддержано с помощью некоторой магии try / catch в Autofac.Что произойдет, если OnRelease() сгенерирует два разных компонента?Мы не можем распространять оба исключения.Далее - когда из Autofac появилось исключение, кто может его поймать?Все компоненты, обслуживающие запрос, теперь освобождены.

Надеюсь, это поможет, Ник.

0 голосов
/ 27 февраля 2011

Я не знаю о NHibernate ISession в Autofac, но если в вашем классе сеанса есть метод Dispose (), вы его нигде не вызываете.Вы должны добавить блок finally после блока catch и избавиться от него там.

...