‫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 بیندازید.

‫‫‫استفاده از الگوی mvp

حتماً تا به حال اسم mvp را چندین و چند بار شنیده و مطالبی را هم راجع به آن خوانده‌اید. mvp یک الگوی طراحی شبیه mvc است که بیشتر برای winform استفاده می‌شود. از جمله مزایای mvp عبارت‌اند از:

۱- Seperation of Concerns (جدا سازی بخش‌های مختلف): یعنی هر بخشی باید کار خودش را انجام دهد.
۲- loose coupling: کاهش وابستگی بین بخش‌های مختلف برنامه
۳- قابلیت‌های نگهداری و خوانایی بالا
۴- افزایش قابلیت unit test و تست پذیری
۵- کمک به جدا سازی کار طراح UI و برنامه‌نویس Code behind

پیاده‌سازی mvp هم مثل خیلی از design patternهای دیگر بر خلاف ظاهرش بسیار ساده است. mvp روش چندان عجیبی نیست به طوری که حتی ممکن است روش پیاده‌سازی UIی که خود شما تا حالا استفاده می‌کرده‌اید به طور ناخودآگاه شباهت زیادی به mvp داشته باشد. در روش mvp به ازای هر فرم سه کلاس برای model، view و presenter وجود دارد. البته برای view و model اینترفیس هم وجود دارد. view توسط فرم ویندوزی پیاده‌سازی می‌شود، model به منطق برنامه یا مثلاً دیتابیس وصل است، presenter هم رابط این دو تا است.

بهترین راه یادگیری mvp استفاده از مثال است. برای یادگیری بیشتر به منابع زیر مراجعه کنید:

http://www.dotnettips.info/2009/08/mvp.html
http://www.codeproject.com/KB/architecture/WinForms_MVP.aspx
http://codebetter.com/jeremymiller/2007/07/26/the-build-your-own-cab-series-table-of-contents/