Prism with WCF
Prism היא תשתית מאוד נוחה לבנות ממשק משתמש מורכב שמקבץ לתוך חלון אחד (Shell) מספר מקורות מידע.

בפוסט זה אני רוצה להראות איך אני בונה את הקשר בין ה-UI ל- Web Services ע"י WCF. רצוי מאוד להוריד את הקוד ולקרוא את הפוסט עם קוד פתוח כדי שהדברים יהיו ברורים. ( לחץ כאן )
מה הבעיות איתם אנחנו צריכים להתמודד?
1. איך לקבל Proxy ל- Web Services מבלי שאני מכיר את המימוש ועושה Add Reference ל-Dll של WCF.
2. איך אפשר לעבוד עם ה- Proxy ב- XAML בלבד.
3. איך עובדים עם ה- Proxy ב- Async Mode וגם רואים חיווי ב-UI עד שהקריאה מסתיימת.
4. איך אפשר לקבל Notification מצד השרת.
פתרונות
1. את כל ה- Proxy ים במודל אחד שנקרא לו Communication. בתוך המתודה Initialize של המודל אני רושם ל-Interface את ה- Proxy.
מה קיבלנו? קיבלנו מודל Communication והוא היחידי שעושה Add Reference ל-Dll של WCF. כלומר
ע"י Config אני יכול להחליף מודול זה ולקבל Proxy אחר. צריך להדגיש שה- Interface מוכר לכולם לכן הוא יהיה במודל Common. על מנת להשתמש ב- Proxy בתוך ה- Xaml עם יכולות של DataBinding לארגומנטים של המתודה של ה-Proxy, אני אשתמש ב- Action או ליתר דיוק ב- TargetedTriggerAction.
הערות:
- ה- Xaml נראה ארוך ומסובך אך הוא נוצר ע"י Drag & Drop ב- Blend. ( מלשונית ה- Behaviors ב- Asset)
- ה- UnityContainer באה מ- ViewModel.

יתרונות השיטה:
- בונה המסכים מקבל אוסף של פעולות ( Actions ) שע"י Drag & Drop ב- Blend הוא יכול להוסיף לוגיקה למסכים.
- בהתחלה אפשר לעשות שאין Proxy אמיתי (Mockup) אבל עדין אפשר לבנות את המסך ולשלב את הפעולות.
- הוספת פעולה למסך או ל-UserControl לא מצריכה קוד.
2. הבעיה עם סעיף 2 (בבעיות שיש להתמודד) היא שה- Invoke של ה- Proxy מתבצעה על ה- Thread של ה- UI. בסעיף זה נבצע אותו על Tread אחר וניתן חיווי כל עוד הפעולה לא הסתיימה.

בניתי מחלקה abstract בשם AsyncTargetedTriggerAction שכל מי שיורש אותה צריך לממש את:
- AsyncInvoke היא מפעילה את ה-Proxy בצורה Async.
- BeforeInvoke רצה על Thred של ה-UI כך שנוכל לקרוא את המשתנים מסוג DependencyProperty.
- AfterInvoke רצה על Thred של ה-UI כך שנוכל לכתוב לתוך המשתנים מסוג DependencyProperty את התוצאה.
הערות:
במחלקה AsyncTargetedTriggerAction אני משתמש ב- EventAggregator כדי להפיץ התחלה וסיום של ה- AsyncInvoke. כל ViewModel שרוצה , מאזין לאירועים אלו וזורק את האירועים הרגילים כך ש- EventTrigger יוכל לתפוס אותם ולהפעיל אנימציה ע"י Action. ( למתקדמים, אפשר גם לבנות EventAggregatorTrigger ואז חוסכים את הקוד ב- ViewModel. )
3. ב- WPF כשרוצים שהשרת ישלח Notification מעלים ServiceHost בצד ה-Client. איך ה-Prism עוזר לנו? אנחנו מעלים את ServiceHost במודול ה- Communication. השרות עצמו לא עושה דבר חוץ מלעביר את הנתונים שהגיעו מהשרת לתוך המערכת ע"י ה- EventAggregator. מי שרוצה לקבל את הנתונים נרשם להודעות אלו וגם יכול לקבל אותם על ה-Tread של ה-UI, קיבלנו ע"י כך הפרדה בין ה- WCF לשאר המערכת.
הערות כלליות:
אני מאוד אוהב את היכולות של Visual State Manager (VSM) ואני משתמש איתו בקוד של הדוגמא. ה-VSM נותן לי את היכולת להדליק ולכבות User Control או כל פקד אחר מבלי לכתוב קוד ב- ViewModel זאת ע"י שימוש ב- Actions ו- Triggers. למה זה טוב? אני מאמין שצריך לתת לבוני המסכים (Xaml) את כל הכלים לבנות UI שלם, כלומר כל מה שמתחיל כתוצאה מפעולה של המשתמש. אם מכינים תשתית טובה של Actions ו- Triggers אפשר לבנות את רוב ה- UI ב- Blend והמפתחים מתמקדים בלוגיקה ולא ב-UI.