‫رکورد اضافی در NHibernate

من مشکلی با NHibernate دارم که نمی‌دانم آیا بقیه هم این مشکل را با NHibernate یا دیگر ORMها یا حتی ADO دارند یا نه. البته اصل این مشکل در صفحات ASP.NET Webform وجود دارد. مشکل این است که وقتی می‌خواهم یک آیتم را در دیتابیس ذخیره کنم یا حتی وقتی می‌خواهم یک رکورد را روی صفحه نمایش دهم مجبور می‌شوم یک یا چند رکورد اضافی را هم از دیتابیس بخوانم.

به عنوان مثال یک صفحه ASP.NET را به شکل زیر تصور کنید:





protected void btnSave_Click(object sender, EventArgs e)
{
Company company = new Company()
{
City = City.Find(drpCity.SelectedValue),
Address = txtAddress.Text
};

company.Save();
}


protected void Search()
{
IList result = MyCustomSearch.SearchCompanies(
City.Find(drpCity.SelectedValue), txtAddress.Text);

//display results in GridView
}

در صفحه بالا، همه Cityها به طور خودکار به drpCity بایند می‌شوند. سپس با کلیک روی دکمه btnSave یک Company با کمک اطلاعات txtAddress و drpCity ذخیره می‌شود. البته کد بالا با Castle ActiveRecord نوشته شده ولی اصل مشکل با دیگر ORMها همان است. همان طور در متود btnSave_Click مشاهده می‌کنید من مجبور هستم برای ذخیره آبجکت Company یک بار به دیتابیس مراجعه کرده و City مورد نظر را از آن فراخوانی نمایم. در متود Search هم همین اتفاق می‌افتد چون متود SearchCompanies پارامتری از نوع City نیاز دارد.

مدتی است که با خودم فکر می‌کنم اگر بتوان این مراجعات بی‌مورد به دیتابیس را حذف کرد، به performance بسیار بهتری می‌رسیم. به همین دلیل به دنبال راه‌هایی هستم که نیاز به load مجدد object را از بین ببرد. در اولین قدم می‌توان همه‌ی متودهایی را که به عنوان ورودی به کل object نیاز دارند را پیدا کرده و آنها را طوری تغییر دهیم که صرفاً بتوانند با ID آبجکت مورد نظر کار کنند. مثلاً متود زیر را در نظر بگیرید:

IList SearchCompanies(City city, string address)
{
var query = from company in ActiveRecordLinq.AsQueryable()
where City == city
select company;

//...
}

این متود را به راحتی می‌توان طوری تغییر داد که به جای City از CityID استفاده کند:

IList SearchCompanies(long cityID, string address)
{
var query = from company in ActiveRecordLinq.AsQueryable()
where City.ID == cityID
select company;

//...
}

‫آیا NHibernate انتخاب خوبی به عنوان یک ORM است؟

اگر در مورد لزوم استفاده از ORM به جواب مثبت رسیده‌اید، انتخاب یک ORM کار چندان  سختی نیست. در حال حاضر ORMهای تجاری و غیر تجاری زیادی وجود دارند از جمله ADO.NET Entity Framework، LLBLGen Pro، SubSonic و… برای دیدن فهرست آنها می‌توانید به این لینک مراجعه کنید.

NHibernate یک ORM کد باز است که از دنیای جاوا وارد دات‌نت شده است. کد باز بودن آن خود به خود مزایای زیادی ایجاد می‌کند. از جمله: جامعه استفاده کنندگان بیشتر، تنوع محصولات جانبی، عدم نیاز به کرک و قفل‌شکنی، عدم وابستگی به ‎.Net Framework و…

از آنجا که NHibernate بر اساس پروژه‌ی جاوایی Hibernate ایجاد شده از تمام تکنیک‌ها و منابع آموزشی آن می‌توان در NHibernate نیز استفاده کرد. NHibernate مدت‌هاست که چه در جاوا و چه در دات‌نت مورد استفاده است و منابع، نمونه کدها و پروژه‌های زیادی بر اساس آن به وجود آمده.

در مورد NHibernate پروژه‌های جانبی زیادی وجود دارد که کار کردن با آن را خیلی راحت‌تر ساخته است. مثلاً Fluent NHibernate به عنوان ابزاری که با کمک آن دیگر نیازی به استفاده از Xml Mappingهای NHibernate یعنی HBMها وجود ندارد. NHibernate Profiler ابزاری برای بازرسی و افزایش سرعت NHibernate. پروژه‌ی Castle ActiveRecord به عنوان ابزار راحت‌کننده‌ی کار با NHibernate و چندین پروژه‌ی مفید دیگر.

یکی از نگرانی‌های همیشگی در کار با ORMها Performance است. مسلماً هر ORMی مقدار کمی سرعت را کاهش می‌دهد. چون ORM یک لایه‌ی اضافی بر روی ADO.NET است. اما این موضوع در برابر دیگر مزایایی که استفاده از ORM به دست می‌دهد قابل اغماض است. البته این کاهش سرعت عمدتاً به علت عدم تنظیم صحیح ORM یا طراحی غلط Class Diagram است و می‌توان آن را تا اندازه‌ی زیادی از بین برد.

در این مورد که آیا NHibernate را می‌توان در پروژه‌های بزرگ به کار برد یا نه فکر نمی‌کنم در مورد پروژه‌هایی که داخل کشور به کار می‌روند مشکل خاصی ایجاد کند. تصور من این است که NHibernate خودش یک چیزی مثل ADO.NET است و می‌تواند بدون توجه به بزرگی یا کوچکی پروژه، یک Performance قابل قبول را از خودش به نمایش بگذارد.

ما در شرکت قبلی استفاده‌های خیلی خوبی از NHibernate کرده و از خیلی از مزایای آن بهره برده بودیم. اما متاسفانه در مقوله‌ی Performance مشکلاتی داشتیم که باز هم  عمدتاً مربوط به عدم استفاده صحیح ما از NHibernate بود. مطمئنم که با استفاده مناسب‌تر و داشتن دانش فنی عمیق‌تر از NHibernate می‌توانستیم مشکل Performance را هم از سر راه برداریم. با این وجود توصیه‌ام به کسانی که قصد استفاده از NHibernate را دارند این است که قبل از شروع حسابی مستندات آن را مطالعه کنند و یکی دو نمونه هم با آن بسازند. ضمناً در مورد طراحی Class Diagramهای دیتابیسی نهایت دقت را به عمل آورند در غیر این صورت حسابی به دردسر خواهند افتاد.

یکی از مشکلات موجود با NHibernate، راه‌اندازی اولیه آن است. منظور از راه‌اندازی اولیه، نوشتن Data Access Layer برنامه با استفاده از آن است. این کار علاوه بر این که وقت‌گیر و حوصله‌بر است، کار حساسی نیز هست. چون در صورت طراحی غلط مشکلات زیادی به وجود خواهد آمد. توصیه این است که برای رفع این مشکل از پروژه‌ی Castle ActiveRecord استفاده کنید. ActiveRecord تقریباً یک Data Access Layer کامل است که کار با NHibernate را به شدت راحت‌تر می‌کند. خصوصاً این که با Castle ActiveRecord مشابه Fluent NHibernate دیگر نیازی به Xml Mapping وجود ندارد. علاوه بر این چون Castle ActiveRecord بر اساس NHibernate نوشته شده تمام امکانات NHibernate را هم هنوز می‌توان با آن استفاده کرد. مثلاً می‌توان با NHibernate.ISession به طور مستقیم در Castle ActiveRecord کار کرد.

توجه: این مطلب در ادامه نوشته‌ی «آیا ORM برای ما مناسب است؟» نوشته شده است.

‫آیا ORM برای ما مناسب است؟

یکی از دوستان می‌خواهد بداند آیا استفاده از NHibernate در یک پروژه‌ی بزرگ با توجه به تجربه‌های قبلی آن، کار درستی است یا نه. این سوال را باید به دو قسمت تقسیم کرد. اول این که آیا استفاده از ORM به طور کلی کار درستی است یا نه. و دوم این که آیا استفاده از NHibernate به عنوان ORM کار درستی است یا نه. در این نوشته به سوال اول می‌پردازیم: آیا استفاده از ORM برای شرکت ما کار درستی است؟ سوال دوم در نوشته‌ی دیگری مورد بررسی قرار خواهد گرفت.

در دنیای Object Oriented Programming کار مستقیم با دیتابیس یک معضل حساب می‌شود. چون به خاطر ماهیت رابطه‌ای بودن آنها نمی‌شود با آنها مثل object برخورد کرد. به همین خاطر ORMها به وجود آمدند تا دیتابیس را زیر خودشان مخفی کرده و آن را به شیوه‌ی مناسب object oriented به لایه‌های بالاتر تحویل دهند.

برای استفاده کامل از امکانات ORM باید همه اصول Object Oriented Programming رعایت شود. یعنی تعریف کلاس‌ها، اینترفیس‌ها و روابط بین آنها باید مطابق اصول باشد. مثلاً اگر عادت به استفاده از متغیرهای عمومی دارید، اگر متودها را فقط به صورت استاتیک می‌نویسید، اگر متودهایی می‌نویسید که گاه به ۵۰۰ خط هم می‌رسند، اگر عادت به استفاده از مفاهیم سه‌گانه OOP ندارید، اگر نمی‌دانید Design Pattern چیست و… باید روش خود را تغییر دهید در غیر این صورت استفاده از ORM نه تنها هیچ مزیتی برای شما ندارد بلکه شما را حسابی هم به دردسر خواهد انداخت.

در بحث Documentation در ORM و دیتابیس، مهم‌ترین موضوعی که با آن برخورد می‌کنید این است که دیگر اجازه استفاده از ERD ندارید. بلکه به جای آن باید از UML Class Diagram استفاده کنید. چون ERD بر اساس ماهیت رابطه‌ای است ولی Class Diagram بر اساس ماهیت Object Oriented ساخته شده. اگر افراد گروه شما به ERD عادت دارند و نمی‌توانند یا نمی‌خواهند از Class Diagram استفاده کنند، این یعنی یک زنگ خطر. چون این افراد بعدها مشکلات زیادی را به وجود خواهند آورد.

تعامل با دیتابیس یکی از بنیادی‌ترین تغییراتی است که استفاده از ORM ایجاد می‌کند. ORMها این تفکر را تبلیغ می‌کنند که عملیات داده‌ای در سمت کد اتفاق بیفتند نه در داخل دیتابیس. این یعنی حداقل استفاده از امکانات داخلی دیتابیس. به عبارت دیگر اگر می‌خواهید از ORM استفاده کرده و از همه مزایای بهره‌مند شوید باید استفاده از Stored Procedureها، Viewها، Triggerها و… را بی‌خیال شوید. حال اگر در شرکتی هستید که همه Business برنامه را از طریق Stored Procedureها، Triggerها، Viewها و… اعمال می‌کنند، بدانید که استفاده از ORM در آنجا خیلی سخت بوده و مخالفان سرسخت زیادی خواهد داشت.

تجربه‌ای که ما در شرکت قبلی داشتیم در بعضی جاها با خودش شکست به همراه داشت. البته میزان موفقیت در استفاده از ORM از نظر شخص خودم حداقل ۷۵ درصد بود. متاسفانه علت آن بخش‌های ناموفق فقر دانش خودمان در استفاده از ORM بود. مهم‌ترین آن‌ها عبارتند از:

۱- چون نتوانسته بودیم ORM خودمان را به خوبی Config کنیم دچار مشکل Performance شده و مجبور شده بودیم بعضی جاها استثنا قائل شده و از Store Procedure استفاده کنیم.

۲- در صفحات ASP.NET برای Data Binding از ObjectDataSource استفاده نکرده بودیم در نتیجه مجبور شده بودیم بیشتر کارها از جمله Paging و… را از طریق code behind انجام دهیم. این موضوع باعث حجیم شدن و پیچیده شدن بیهوده‌ی code behind شده بود. علت عدم استفاده از ObjectDataSource نا آگاهی خودمان بود ولی به هر صورت اگر از به جای ORM از ADO.NET استفاده می‌کردیم کمتر دچار این مشکلات می‌شدیم.

۳- ما برای گزارش‌گیری از MS SQL Server Reporting Services استفاده می‌کردیم. گزارشات در این سیستم به دو نوع client و server تقسیم می‌شوند. ما بلد نبودیم یا شاید هم راهی وجود نداشت که خروجی‌های objectی مثل IList را به گزارشات سروری بفرستیم. در نتیجه آنجا هم مجبور شدیم برای تهیه گزارشات به صورت مستقیم از Sql استفاده کنیم.

توصیه شخصی من برای استفاده یا عدم استفاده از ORM این است که با توجه به پیشرفت فناوری‌ها و گرایشات روز دنیای نرم‌افزار و با توجه به رواج روز افزون روش‌های Agile و TDD بهتر است شما هم هر چه زودتر خودتان را به جمع کاربران ORM اضافه کنید. درست است که ORM درصد خیلی کمی از سرعت برنامه را کاهش می‌دهد، تغییرات زیادی را در روش کار می‌دهد و نیاز زیادی به آموزش و مطالعه دارد، اما در مجموع هزینه‌های تولید را کاهش می‌دهد، نگهداری کد را راحت‌تر می‌کند، تعداد باگ‌ها را کاهش می‌دهد و در نهایت هم منافع کارفرما و مدیریت را با خود به همراه دارد و هم رضایت برنامه‌نویسان را.

Saving time as UTC with NHibernate

In many applications that have world wide users, there is a need to dealing with UTC. In these applications, time is stored in UTC and then showed backed in local time to users. A good solution is not to bother developers to convert time to universal or local time every time manipulating time related data. Instead we could add a bit of code to setter getter of DateTime fields. Unfortunately this solution does not work in NHibernate and possibly other ORMs. Consider following code:

DateTime _myDate;

[Property]
public virtual DateTime MyDate
{
    set { _myDate = value;}
    get {return _myDate;}
}

In this code we can not add a ToLocalTime() or ToUniversalTime() to setter or getter. Because both NHibernate and the application use this same getter and setter. Real solution is to use a helper field. This way the helper field will not persist on database but real field persists on database. Real field mus not be accessible to developer because of confusion and possible unwanted changes. Consider final solution:

public virtual DateTime MyDate //helper field
{
    set { MyDateUtc = value.ToUniversalTime(); }
    get { return MyDateUtc.ToLocalTime(); }
}

[Property]
private DateTime MyDateUtc { set; get; } //real field

All codes are based on Castle Active Record.

استفاده از مفاهیم جدید تولید نرم‌افزار

روند طراحی و توسعه نرم‌افزار طی ده سال گذشته حتی در همین ایران خودمان هم تغییرات زیادی داشته. آن زمان یعنی حدود سال ۷۹ شمسی مردم تازه از شر FoxPro خلاص شده و به دیتابیس‌های مدرن‌تری مثل Access، MS SQL Server و Oracle رو آورده بودند. برنامه‌نویسی در عصر ویندوز راحت‌تر و منظم‌تر شده بود. تا قبل از آن عموماً کسی لذت Foreign Key و Delete/Update Cascade را کشف نکرده بود. طی این ده سال استفاده از Database Driver و ADO رواج زیادی پیدا کرد. در این دوره آنها که منظم‌تر بودند از نمودارهای ERD برای بیان ساختار دیتابیس، نرمال‌سازی، کلاس‌های مجزا برای دسترسی به دیتابیس (معماری سه لایه) و… استفاده می‌کردند.

اما اکنون آن دوران به سر آمده و ما خیلی وقت است که وارده دوران Domain Driven Design یا همان DDD شده‌ایم. در عصر DDD هیچکس مستقیماً به دیتابیس وصل نمی‌شود بلکه از ORM‌ استفاده می‌کند. روابط بین entityها به جای ERD با UML Class Diagram تعریف می‌شود و معماری‌های چندلایه‌ای با استفاده از DDD خیلی راحت‌تر شده و…

حال سوال این است که آیا لازم است ما هم صرفاً به خاطر همراهی با زمان یه سمت Domain Driven Design و Object Oriented برویم یا این که واقعاً نفعی برای ما و شرکت‌مان در آن وجود دارد؟ جواب این سوال هر دو است. چون اولاً وقتی که همه دنیا به این سبک جدید رو آورده‌اند خیلی سخت است که ما همان روش‌ها و ابزارهای قدیمی را نگه داریم و خلاف جریان آب شنا کنیم. ثانیاً عصر جدید امکانات بسیار خوبی را با خود به همراه آورده است و نباید آن را به این سادگی از دست بدهیم.

عصر جدید یعنی دنیای Domain Driven Design و Object Oriented که با استفاده از ORMها و UML محقق می‌شود به شما کمک می‌کند که:
‫۱- کد شما قابلیت نگهداری بالایی داشته باشد.
‫۲- پیدا کردن و برطرف کردن باگ‌ها راحت‌تر باشد.
‫۳- اگر طراحی درست انجام شده باشد، برنامه‌نویسی راحت‌تر خواهد بود.
‫۴- مزایای معرفی شده در Object Oriented به طور ملموسی در دسترس قرار خواهد گرفت. مفاهیمی مثل Inheritance باعث می‌شود حجم کد کاهش یابد.
‫۵- کدهای DDD خیلی منظم‌تر از کدهای تولید شده در دوران قبل هستند.
‫۶- تولید نرم‌افزارهای DDD هم‌خوانی بسیار بیشتری با متودولوژی‌های جدید اسکرام، XP و… دارد.
‫۷- …

در بین شرکت‌ها و تیم‌های نرم‌افزاری ایرانی تعداد قابل توجهی به روش‌های عصر جدید رو آورده‌اند. یعنی از ORM استفاده می‌کنند، کل کار را به صورت Object Oriented جلو می‌برند، Documentation آنها بر اساس UML است و … اما متاسفانه هنوز خیلی‌ها هستند که خود را از لذت و کارایی عصر جدید محروم کرده‌اند. به نظر من تنها عاملی که باعث می‌شود این طور افراد همچنان به استفاده از روش‌های قدیمی ادامه دهند عدم آگاهی نسبت به روش‌های جدید است. چون هیچ مدیر پروژه یا رییس شرکتی دوست ندارد کاری را که می‌شود در شش ماه انجام داد در هشت ماه انجام دهد و نهایتاً هم کدی را تحویل بگیرد که نگهداری و توسعه آن خیلی هم سخت باشد. به همین خاطر به این طور افراد توصیه می‌گردد اگر هم از روش‌های قدیمی خیلی هم راضی هستند اقلاً مطالعه‌ای در مورد روش‌های جدید و مزایای آن داشته باشند.

‫lazy loading در NHibernate

lazy loading از آن قابلیت‌های جالبی است که همه دوست دارند آن را در برنامه خود داشته باشند. با کمک lazy loading که تقریباً همه ORMها آن را پیاده‌سازی کرده‌اند می‌توان بازیافت اطلاعات از دیتابیس را تا حداکثر زمان ممکن به تعویق انداخت. مثلاً فرض کنید آبجکتی به اسم obj1 دارای یک property به نام obj2 است که obj2 کلاسی است که اطلاعات آن از دیتابیس load می‌شود. در حالت lazy loading وقتی که obj1 از دیتابیس load می‌شود، صرفاً اطلاعات خودش load می‌شود مگر آن که عبارتی به شکل object o1 = obj1.obj2 فراخوانی شود. تازه در این مرحله است که اطلاعات obj2 هم از دیتابیس فراخوانی می‌شود. به این مدل فراخوانی اطلاعات از دیتابیس lazy loading گفته می‌شود چون تا زمانی که واقعاً نیاز به اطلاعات obj2 نباشد، اطلاعات آن از دیتابیس فراخوانی نخواهد شد. lazy یعنی تنبل.

lazy loading در ORMهای مختلف به روش‌های مختلفی انجام می‌شود. مثلاً بعضی‌ها از روش Inheritance استفاده می‌کنند. به این معنی که کلاس Business Entity شما بایستی از یک کلاس مخصوص ارث‌بری کند. این کلاس مخصوص خودش دارای متودهایی برای انجام عملیات lazy loading است. بعضی ORMهای دیگر از روش interface استفاده می‌کنند. در این روش کلاس Business Entity شما باید interface خاصی را implement کند. اما روش NHibernate استفاده از design pattern جالبی به اسم proxy است. در این روش NHiberntae به هنگام شروع به کار و ساختن session، به ازای هر کدام از کلاس‌های Business Entity شما یک کلاس مخصوص می‌سازد و هر جا که برنامه شما نیاز به استفاده از آن کلاس پیدا کرد، NH آن کلاس proxy را تحویلش می‌دهد. این قضیه از دید برنامه مخفی است. یعنی برنامه فکر می‌کند همچنان در حال استفاده از کلاس خودش است. به این ترتیب NH این فرصت را پیدا می‌کند که درخواست‌های دسترسی به propertyهای مختلف یک object را به جای آن که مستقیماً به دیتابیس بفرستد به آن کلاس proxy بفرستد. آن کلاس proxy هم خودش ترتیب lazy loading را می‌دهد. برای آن که یک کلاس proxy بتواند به وظیفه‌اش عمل کند باید کلیه propertyها و methodهای کلاس مبدا به صورت virtual تعریف شده باشد تا proxy factory بتواند همه آنها را در کلاس proxy ارث برده شده، override کند. NH برای تولید proxy از کتابخانه‌های مستقلی مثل Castle Dynamic Proxy استفاده می‌کند.

lazy loading در NH در سه سطح عمل می‌کند: الف- در سطح object. یعنی تا زمانی که واقعاً نیاز به خواندن اطلاعات objectهای دیگری که به صورت property تعریف شده‌اند نباشد، اطلاعات آن از دیتابیس خوانده نخواهد شد. NH فعلا lazy loading در سطح propertyهای غیر آبجکتی را پشتیبانی نمی‌کند.  ۲- در سطح کلی collection: تا زمانی که نیاز به اطلاعات یکی از اعضای آن collection نباشد، اطلات آن از دیتابیس بازیافت نخواهد شد. در این روش همیشه کل collection با هم خوانده می‌شوند. ۳- در سطح اعضای collection: درست مشابه روش قبل است با این تفاوت که lazy loading در سطح تک تک اعضای collection انجام می‌شود. مثلا وقتی که به عنصر چهارم یک collection نیاز هست فقط query همین یک رکورد به دیتابیس ارسال می‌شود نه دیگر اعضای collection. این حالت lazy loading به طور پیش‌فرض به خاطر جلوگیری از کندی سرعت غیر فعال است.

تنها مشکلی که با lazy loading وجود دارد، مشکل آن با session است. در مورد مثال بالا اگر obj1 در حین فعال بودن یک session از دیتابیس فراخوانی شود و آن session بدون فراخوانی obj1.obj2 بسته شود و فراخوانی پس از بسته شدن session انجام شود، خطا رخ می‌دهد چون آن object دیگر detach شده است. غلبه بر این مشکل خیلی سخت نیست. فقط کافی‌ست Close شدن session تا حد امکان به تعویق انداخته شود، مثلا به آخرین خط متود یا try-catch منتقل شود. و اگر این امکان‌پذیر نبود قبل از بسته شدن session، آن property مورد دار به صورت الکی فراخوانی شود تا برنامه یک بار مجبور شود به دیتابیس مراجعه کرده و اطلاعات خود را به روز کند. مشکل sessionها بیشتر در برنامه‌های web مشکل‌ساز هستند چون برنامه‌نویس مجبور است با هر بار Postback برنامه، session را ببندد.

‫WPF بهتر است یا WinForms؟

 ‫معماری wpf

wpf به عنوان رقیبی جدی برای winforms از framework 3.0 به مجموعه دات‌نت اضافه شد. winforms از ابتدای تولد دات‌نت وجود داشته و تا حالا رشد خیلی زیادی کرده است. منابع بسیار زیادی درباره آن وجود دارد، برنامه نویسان زیادی به آن تسلط پیدا کرده اند و تعداد بسیار زیادی برنامه نوشته شده با آن موجود است. در آن سوی این رقابت wpf قرار دارد. wpf به زعم خیلی ها جایگزین winforms است و مایکروسافت با وجود آن دیگر winforms را توسعه نخواهد داد و صرفا به پشتیبانی آن اکتفا می‌کند. wpf به مذاق طراحان UI و عشاق گرافیک های آن چنانی بسیار خوش آمده است. ما هم به علت در پیش رو داشتن پروژه‌های جدید ویندوزی و به خاطر اینکه از قافله جهانی عقب نمانیم نظرات بعضی از مدافعان و مخالفان را بررسی کرده و به جهت فهم خودمان و استفاده دیگران خلاصه وار در اینجا می آوریم:

۱- wpf فقط روی ویندوز ویستا، ویندوز 2008، win xp sp2 و آخرین RDP ویندوز 2003 کار می‌کند.
۲- بسیار گفته شده که wpf در حوزه کنترل‌های کار با دیتا مثل DataGrid کمبودهای زیادی دارد. البته با وجود این ضعف گفته می‌شود که wpf در DataBindingهای آبجکتی مرسوم در دنیای Domain Drivern Design خیلی خوب عمل می‌کند. این مدل DataBinding از همان نوعی است که همراه با ORMهایی مثل NHibernate و LINQ رایج شده است.
۳- استدلال تعدادی از افراد برای عدم استفاده از wpf عدم علاقه آنها به دست کشیدن از دانسته‌ها و مهارت‌های قبلی‌شان در winforms و یادگیری تکنولوژی جدید wpf است. اگر شما هم مثل ما تجربه چندان با ارزشی روی winforms ندارید می‌توانید با انگیزه بیشتری به wpf فکر کنید.
۴- wpf یک عمو زاده دارد به نام SilverLight که هر دو در استفاده از XAML مشترک هستند. هر چند که SilverLight زیرمجموعه‌ای از wpf محسوب می‌شود ولی می‌توانید امیدوار باشید که با یادگیری wpf خود به خود کمی هم SilverLight یاد گرفته‌اید.
۵- wpf برای تولید و نمایش UI از خیلی از امکانات DirectX ،GPU و حافظه کارت گرافیک استفاده می‌کند و رابطه خیلی خوبی با پخش انواع فایل تصویری، ویدیویی، صوتی و انیمیشن دارد.
۶- ادعا می شود که کد منطق برنامه و کد Prsesentation در wpf کاملا از هم جداست. یعنی می توان کد XAML را به فردی که هیچ اطلاعاتی راجع به C#‎ ندارد سپرد تا آن را با Expression Blend حسابی عمل بیاورد. کد سی‌شارپ هم می‌تواند توسط یک برنامه‌نویس متعارف در Visual Studio توسعه پیدا کند.
۷- علی القاعده در برنامه های فارسی و آنهایی که از تقویم شمسی استفاده می‌کنند مشکلات زیادی وجود خواهد داشت. چون هنوز هیچ‌کس یک DatePicker فارسی با wpf ننوشته است و رفتار بقیه کنترل‌ها هم در محیط‌های پیچیده راست به چپ نویسی معلوم نیست. البته در مستندات خود wpf ذکر شده که پشتیبانی خیلی خوبی از یونیکد و مسایل localization وجود دارد.
۸- اگر خیلی از ژیگول‌بازی‌های wpf و wpfدوستان خوشتان نمی آید اصلا نامید نشوید چون winforms حالا حالاها زنده خواهد بود. همان طور که هنوز VB6 و حتی FoxPro زنده هستند.
۹- اگر برای اتمام پروژه ای عجله دارید از wpf استفاده نکنید چون ممکن است بدجوری شما را غافل‌گیر کند.
۱۰- برای یادگیری از کتاب زیر شروع کنید (بنا به توصیه دوستان wpf):
Windows Presentaion Foundation Unleashed by Adam Nathan
۱۱- بعضی امکانات جدید به wpf اضافه شده‌اند که من هنوز از بیشتر آنها سر در نمی‌آورم:

  • UI Automation
  • UI Virtualization
  • Routed Events
  • Attached Properties
  • Property change notification
  • XBAP