בהמשך לטיפים הקודמים שהיו לפני כמה זמן, נראה עכשיו עוד שיטה ליצור Interception לאובייקטים.
ממליץ לקרוא את הטיפים הקודמים כדי להזכר (350-362)
השיטה הפעם נקראת Compile-time IL weaving.
מה זה?
הרעיון הוא הרעיון המטורף הבא:
אחרי שאנחנו מקמפלים אפליקציה, נוצרים לנו DLLים המכילים את הקוד של האפליקציה שמקומפל לשפת ביניים (מה שנקרא CIL או MSIL, תלוי מתי שאלתם).
Compile-time IL weaving מציע לקחת את הDLL שנוצר, ולשנות את הIL שנוצר, כך שיבצע התנהגות שונה, ועל ידי כך להשיג את הInterception.
הIL לאחר השינוי נשמר בDLL, כך שהשינוי הוא שינוי סטטי. (לא מתבצע בזמן ריצה)
אז איך עושים את זה? יש מספר APIים בעולם המאפשרים לפרסר IL ולבצע עליו מניפולציות, ביניהם: Mono.Cecil, Microsoft.CCI, PostSharp API.
בד”כ לא נרצה להשתמש בהם ישירות מאחר וזו משימה יחסית מסובכת לערוך את הIL בלי לעשות נזק, וגם לדאוג שמה שרצינו לעשות יעבוד.
למרות שלפעמים יחסית קל להשתמש בהם כדי לעשות דברים פשוטים, למשל לשנות את הProperties של המחלקות שלנו שיקראו לPropertyChanged של INotifyPropertyChanged (יש דוגמאות באינטרנט לדבר הזה)
במידה ונעשה משהו כזה, האידיאל יהיה שיהיה איזשהו Post build event בSolution שלנו שמריץ את השינוי של הIL על הDLLים המקומפלים.
קיימים Frameworkים יחסית מפותחים, ביניהם AfterThought וPostSharp המאפשרים לנו לבצע את הפעילות הזו בזמן קימפול בצורה נוחה.
PostSharp הוא הFramework המוביל בשוק בתחום הזה ומה שהוא נותן זה מימוש לAOP (ראו גם טיפ מספר 358) באמצעות Compile-time IL weaving:
איך זה נראה? אנחנו צריכים לרשת מAttributeים של התשתית, למשל
|
|
ואז לשים אותם מעל הפונקציות שלנו, למשל:
|
|
בפועל יקרא הקוד שלנו. בואו נסתכל על הקוד שיוצא בReflector:
|
|
מה שאנחנו רואים פה זה שנקרא שלפני ביצוע הקוד שלנו, מתבצעת קריאה לOnEntry. כאשר נתפס Exception, מתבצעת קריאה לOnException, וביציאה למתודה מתבצעת קריאה לOnExit.
מה שמגניב זה שיש Member בשם mAspects (זה לא באמת השם שלו, אבל לצורך העניין) שמכיל את האובייקטים של הAttributeים והמתודות, והוא נוצר בגישה הראשונה של המחלקה שלנו, כך שבעצם מתבצעת קריאה ישירות למתודה (ולא ע"י עטיפה כמו שראינו בדוגמאות של הRuntime Subclassing), כך שהקוד שנוצר הוא ממש מהיר.
מה שכן, צריך לשים לב לדברים הבאים:
- PostSharp, הכלי המוביל בשוק, הוא לא חינמי ועולה קצת כסף. שאר הכלים פחות טובים
- הדבר הזה קצת מוזר בדיבוג – אנחנו נראה שאנחנו נכנסים לקוד שבAttribute בכניסה למתודה, למרות שלא ראינו בקוד קריאה אליו.
למרות זאת, מדובר בכלי מאוד חזק שיכול להיות מאוד שימושי לכתיבת תשתיות.
המשך יום מקומפל ארוג לטובה.