בהמשך לפעם הקודמת, הפעם נראה כיצד ניתן לממש תשתית Interception בעצמנו.
הדרך הראשונה היא באמצעות משהו שנקרא ContextBoundObject. זה מאוד מזכיר את RealProxy (טיפ מספר 348).
שוב, תזכורת:
אנחנו מעוניינים באיזשהו ממשק של הFramework שאם נממש אותו נקבל יכולת Intercept לאובייקטים שלנו.
ContextBoundObject הוא אובייקט שיורש מMarshalByRefObject – נאמר שתי מילים על MarshalByRefObject:
ב.net קיימת אופציה לסרלז אובייקט: להפוך אותו לייצוג בינארי. כך אפשר להעביר אובייקטים בין השאר בין כמה AppDomainים. MarshalByRefObject הוא אובייקט שהCLR יודע לסרלז אותו באופן מיוחד: הוא מסרלז אותו בצורה כך שכאשר הוא עובר לAppDomain אחר, הוא מועבר לפי הReference שלו.
ContextBoudObject מאפשר יותר שליטה על האובייקט בCLR ובעצם מאפשר להתערב בקריאות של הפונקציות של האובייקט שלנו.
אז איך זה עובד?
זה קצת מסובך להשתמש בזה Out of the box, אבל ניתן לעשות זאת עם קצת (או קצת יותר) זיעה. להלן מימוש של LogInterceptor באמצעות ContextBoundObject:
|
|
תכלס זה קצת קשה להבין מה קורה כאן:
נתחיל בסוף: מה שבאמת חשוב כאן זאת הפונקציה SyncProcessMessage שמשנה את ההתנהגות לקריאה לפונקציה ומבצעת במקומה התנהגות משלנו.
(מזכירה את Route שתמיד ראינו כשדיברנו על Interception)
כל שאר הסיפור שיש כאן זה מה שצריך לעשות בFramework של ContextBoudObject כדי שתקרא הפונקציה SyncProcessMessage. (למען האמת, אני לא מכיר את זה לעומק, ויכול שיש פה טיפה יתירות)
זה רק הרקע שצריך לעשות כדי לכתוב את הInterceptor. כדי להשתמש בו, זה יותר קל:
נירש מContextBoundObject ונשים את הAttribute שלנו:
|
|
עכשיו כשנקרא לפונקציות של האובייקט שלנו, הן תעבורנה דרך הInterceptor 😀:
|
|
כמה הערות:
מן הסתם אפשר לכתוב Framework שיקטין משמעותית את כמות הקוד שיש פה. בצוות שלי עשינו משהו, ואז כתיבת Interceptorים פשוט נראה כך:
|
|
אותו שמים פשוט מעל מתודה שאנחנו רוצים שתכתוב לLog את הExceptionים.
הערה נוספת:
זאת דרך אפשרית לממש Interception. היתרון המובהק שלה שהיא יחסית Built in בFramework.
יש לה די הרבה חסרונות:
- ContextBoundObject לא נחמד בדיבוג – נראה בWatch ובשאר חלונות הדיבוג הערה ש"מדובר בProxy ולכן אי אפשר לראות אותו בWatch".
- ContextBoundObject כמו RealProxy וחבריו איטי יותר. אני לא אערוך פה השוואה, אבל אני מניח שמדובר באותם סדרי גודל, אם לא איטי יותר.
כאמור זאת רק דרך אחת לממש Interception. נראה בהמשך עוד דרכים נוספות למימוש ונשווה בין השיטות.
המשך יום עם Context חסום לטובה.