בהמשך לפעם הקודמת, נראה עכשיו שיטה נוספת למימוש Interception.
ראינו בעבר איזשהי שיטה באמצעות Decorator (ראו גם טיפ מספר 353).
באופן דומה לטיפ מספר 349, די מבאס (וקשה!) לכתוב את המימוש של הממשק כך שיתמוך בInterception.
מה שאפשר לעשות זה את הדבר הבא: באופן דומה לטיפ מספר 349, ניצור טיפוס בזמן ריצה שיורש מהטיפוס שלנו (או לחלופין מממש את מהממשק שלנו) ומבצע את הInterception שלנו.
כמו בטיפ מספר 349, ניתן לעשות דבר כזה ע”י שימוש בReflection.Emit.
כמו בטיפ ההוא, אני לא אראה כאן איך מממשים דבר כזה בReflection.Emit, ואראה במקום זאת שימוש בFramework קיים שנקרא DynamicProxy של Castle שיודע לבצע את זה.
נניח שאנחנו מעוניינים בLoggingInterception: בDynamicProxy יש ממשק בשם IInterceptor שנוכל לממש:
|
|
כאשר IInvocation הוא הממשק של Castle שמייצג קריאה לפונקציה.
זהו הממשק של Castle לInterception (ראו גם טיפ מספר 357)
כעת אנחנו יכולים לממש אותו כאוות נפשנו:
|
|
כעת נצטרך ליצור טיפוס ולהתקין עליו את הInterceptor הזה. זה נעשה באופן דומה למה שראינו בטיפ מספר 357:
|
|
הערות:
- הביצועים של שימוש בטכניקה כזאת היא יותר מהירה בעשרות מונים משימוש בContextBoundObject שכבר ראינו אותו
- אין חובה לעשות Interception לInterface, ניתן גם לטיפוס עצמו: כל עוד הוא לא Sealed, נוכל לעשות Intercept לכל המתודות הוירטואליות שלו.
סופ"ש עם ירושה בזמן ריצה טוב.