‫NHibernate session management در محیط‌های مختلف

مهم‌ترین مسئله‌ای که در Session management در NHibernate وجود دارد، مسئله نگهداری session است. به طور معمول سعی می‌شود برای انجام یک کار فقط یک session باز شود نه بیشتر. اگر طی انجام همان کار مجدداً نیاز به session شد از همان session قبلی استفاده می‌شود نه این که یک session جدید open شود.

این کار در وب خیلی راحت است. session instance مورد نظر در HttpContext قرار داده می‌شود. در مورد ویندوز و WCF هم کار چندان سختی نیست. چون از Thread برای نگهداری session استفاده می‌شود. اما موقعیت‌هایی وجود دارد که می‌خواهیم به طور هم زمان در دو محیط از یک Session Factory و Session استفاده نماییم. مثلاً هم وب را داریم و هم یک سرویس WCF را.

این طور وقت‌ها می‌توان یک SessionContext سفارشی ساده ساخت که هم session را در HttpContext نگاه داشت و هم در جای دیگری که در محیط مورد نظر معنی دار است. اصل این راه حل در اینجا توضیح داده شده.

‫NHibernate Session Management در Winform و WCF

بحث NHibernate Session Management در برنامه‌های وب اصلاً کار سختی نیست. روتین‌ها و نمونه‌های زیادی هم در مورد آن وجود دارد. اما انجام همین بحث در Winform و WCF کمی کار می‌برد. یکی از بهترین روش‌ها برای مدیریت Session در NHibernate استفاده از الگوی Unit Of Work است. تطبیق این الگو با مدل کاری وب خیلی ساده است. فقط کافی است فرض کنید شروع هر unit of workی با شروع Web Request توسط کاربر و پایان آن با رندر صفحه و ارسال آن به کلاینت منطبق است.

برای ویندوز و WCF هم که از بسیاری جهات به هم شبیه هستند چند روش وجود دارد. یکی از این راه‌ها conversation per business transaction یا CpBT است. در CpBT منطق کاری (business transaction) مبنای کار است. یعنی شروع unit of work با شروع عملیات کاری و پایان آن با پایان عملیات کاری اتفاق می‌افتد. به عنوان مثال فرض کنید یک منطق یا روال کاری داریم به نام «محاسبه حقوق ماهیانه شخص فلان». در CpBT شروع unit of work وقتی است که کاربر از طریق winform یا wcf روال «محاسبه حقوق» را شروع می‌کند. به عبارت دیگر شروع روال «محاسبه حقوق» توسط کاربر باعث می‌شود یک session از NHibernate دریافت شده و یک Transaction شروع شود. حال هر وقت که کاربر پایان کار را با مثلاً فشردن دکمه تایید به پایان رساند، پایان unit of work هم فرا رسیده و کارهای مرتبط با آن مثل commit شدن transaction هم انجام می‌شود. دقت شود که اگر از الگوی CpBT استفاده نمی‌شد ممکن بود در حین کاری مثل محاسبه حقوق که چندین و چند مراجعه به دیتابیس و چند modify اطلاعات دارد، مجبور شویم چندین session از NHibernate گرفته و چندین بار commit transation داشته باشیم. که هم کار را خیلی کند می‌کند و هم مدیریت transactionها را غیر ممکن می‌کند.

برای اعمال CpBT در NHibernate و WCF و Winform یک کتابخانه مفید به نام uNhAddins وجود دارد. این کتابخانه تمام این کار را اتوماتیک می‌کند. مثلاً برای آن که بگویید یک متودی از یک کلاس برابر است با نقطه شروع یک CpBT فقط کافی است روی کلاس آن عبارت

[PersistenceConversational(MethodsIncludeMode = MethodsIncludeMode.Implicit)]

و روی متود آن عبارت

[PersistenceConversation(ConversationEndMode = EndMode.End)]

را قرار دهید. البته نیاز به کدها و تنظیمات دیگری هم وجود دارد. از جمله این که اگر WCF کار می‌کنید، از uNhAddIns.SessionEasier.Contexts.ThreadLocalSessionContext به عنوان current_session_context_class در تنظیمات NHibernate استفاده کنید و اگر از WinForm استفاده می‌کنید از uNhAddIns.SessionEasier.Conversations.ThreadLocalConversationalSessionContext استفاده کنید.

به عنوان یک نمونه کامل uNhAddins و CpBT که هم WCF را پوشش می‌دهد، هم WPF را، هم MVP را و هم IoC را، نگاهی به نمونه کد uNHAddins.Examples.SessionManagement در مخزن کد uNhAddins بیندازید.