۱۳۸۹/۰۹/۳۰

NHibernate 3.0 و ارائه‌ي جايگزيني جهت ICriteria API


ICriteria API در NHibernate پياده سازي الگوي Query Object است. مشكلي هم كه اين روش دارد استفاده از رشته‌ها جهت ايجاد كوئري‌هاي متفاوت است؛ به عبارتي Type safe نيست. ايرادي هم به آن وارد نيست چون پياده سازي اوليه آن از جاوا صورت گرفته و مباحث Lambda Expressions و Extension Methods هنوز در آن زبان به صورت رسمي ارائه نشده است (در JDK 7 تحت عنوان Closures قرار است اضافه شود). NHibernate 3.0 از ويژگي‌هاي جديد زبان‌هاي دات نتي جهت ارائه‌ي محصور كننده‌اي Type safe حول ICriteria API استاندارد به نام QueryOver API سود جسته است. اين پياده سازي بسيار شبيه به عبارات LINQ است اما نبايد با آن اشتباه گرفته شود زيرا LINQ to NHibernate‌ يك ويژگي ديگر جديد، يكپارچه و استاندارد NHibernate 3.0 به شمار مي‌رود.
براي نمونه در يك ICriteria query متداول، فراخواني‌هاي ذيل متداول است:
.Add(Expression.Eq("Name", "Smith"))
اكنون شما در NHibernate 3.0 مي‌توانيد دستورات فوق را به صورت ذيل وارد نمائيد:
.Where<Person>(p => p.Name == "Smith")

مزيت‌هاي اين روش (strongly-typed fluent API) به شرح زير است:
- خبري از رشته‌ها جهت استفاده از يك خاصيت وجود ندارد. براي مثال در اينجا خاصيت Name كلاس Person تحت كنترل كامپايلر قرار مي‌گيرد و اگر در كلاس Person تغييراتي حاصل شود، براي مثال Name به LName تغيير كند، برنامه ديگر كامپايل نخواهد شد. اما در حالت ICriteria API يا بايد به نتايج حاصل از Unit testing مراجعه كرد يا بايد به نتايج بازخورد كاربران برنامه مانند: "باز برنامه رو تغيير دادي، يكجاي ديگر از كار افتاد!" دقت نمود!
- اگر در حين ويرايش كلاس Person از ابزارهاي Refactoring استفاده شود، تغييرات حاصل به صورت خودكار به تمام برنامه نيز اعمال خواهد شد. بديهي است اين اعمال تغييرات تنها در صورتي ميسر است كه خاصيت مورد نظر به صورت رشته معرفي نگرديده و ارجاعات به اشياء تعريف شده به سادگي قابل parse باشند.
- در اين حالت امكان بررسي نوع خواص تغيير كرده نيز توسط كامپايلر به سادگي ميسر است و اگر ارجاعات تعريف شده به نحو صحيحي از اين نوع جديد استفاده نكنند باز هم برنامه تا رفع اين مشكلات كامپايل نخواهد شد كه اين هم مزيت مهمي در نگهداري ساده‌تر يك برنامه است.
- با بكارگيري Extension methods و پياده سازي Fluent API جديد، مدت زمان يادگيري اين روش نيز به شدت كاهش يافته، زيرا Intellisense موجود در VS.NET بهترين راهنماي استفاده از امكانات فراهم شده است. براي مثال جهت استفاده از ويژگي جديد QueryOver به سادگي مي‌توان پس از ساختن يك session جديد به صورت زير عمل نمود:
IList<Cat> cats = session.QueryOver<Cat>().Where(c => c.Name == "Max").List();
در اينجا اگر متدهاي نمايش داده شده توسط Intellisense را دنبال كنيم ديگر حتي نيازي به مراجعه به مستندات QueryOver در مورد اينكه چه متدها و امكاناتي را فراهم كرده است نيز نخواهد بود.

جهت مشاهده‌ي معرفي كامل آن مي‌توان به مستندات NHibernate 3.0 مراجعه كرد.