Считается ли механизм Inteceptor Касл Виндзор хорошим / эффективным способом реализации шаблона единиц работы?
В моем проекте задействованы Castle Windsor, NHibernate Facility и, конечно же, NHibernate - все они используются в сервисах WCF, размещенных самостоятельно.
Каждый метод службы обычно запрашивает из контейнера Windsor экземпляр вспомогательного класса, в который делегирован вызов WCF. Вспомогательный класс имеет аргумент конструктора ISessionManager, который Виндзор разрешает с помощью NHibernate Facility.
Проблема в том, что вспомогательный класс выполняет слишком много работы. Он имеет как логику, так и доступ к данным, что делает его трудным (практически невозможным) для тестирования и трудным для чтения.
Я хочу перестроить обязанности
Я не хочу, чтобы помощник WCF ничего знал о транзакциях или сеансах, поэтому нет аргумента конструктора ISessionManager, нет ссылок на транзакции и нет ISession.
Чтобы помощник WCF мог осуществлять доступ к данным, ему придется положиться на нового помощника, смею ли я назвать его DAO? или не дай бог репозиторий, в котором будут методы для извлечения, запроса и, возможно, сохранения объектов домена.
Проблема с возвратом прокси-объектов NHibernate из DAO заключается в том, что если сеанс закрывается до возвращения объекта, любая последующая попытка получить доступ к коллекциям в объекте домена из клиентского кода приведет к исключению, так как сеанс не дольше там будет лениво извлекать необходимые данные. Это на самом деле очевидно, но все новички в NHibernate должны решить эту проблему.
Так что, если DAO и Repos не могут закрыть сеанс, что делает?
Мне нужен один сеанс NHibernate для каждого вызова операции службы WCF, где несколько DAO или репозиториев могут вызывать OpenSession сколько угодно, но все они получают один и тот же сеанс, и в идеале любая попытка удалить сеанс будет игнорироваться если это не последняя утилизация. Не уверен насчет последнего бита, но, возможно, DAO и репозитории просто вызывают ISessionManager.OpenSession и оставляют это для чего-то еще, чтобы очистить и утилизировать сеанс.
Я подумал, что, возможно, я мог бы использовать перехватчик, который принимает ISessionManager, открывает сеанс и запускает транзакцию, пересылает вызов, затем, если исключение не происходит, фиксирует транзакцию и удаляет сеанс, в противном случае откатывает транзакцию, если возникает какое-либо исключение происходит.
Есть мысли?