There are two possible targets for interception:
Types, such as classes or interfaces;
Instances of types.
Depending on the target, we can use different interception techniques.
In .NET, like in other OOP languages, we have the following interception techniques:
Virtual method interception: this is a type interception technique by which we subclass dynamically a target type – an interface or a class, since structures do not allow subclassing – and add method overrides for the methods we want to intercept. Of course, only virtual methods can be intercepted (abstract methods and interface methods are treated as virtual); the interceptor returns an instance of the dynamically generated subclass of the target type, which is treated exactly as if it were this target type;
Interface interception: an instance interception technique. There has to be an existing object for us to intercept, and it must implement one or more interfaces. We can intercept any method or property exposed by one of these interfaces; basically, the generated interceptor code sits between the exposed interface and the existing target;
Transparent proxy interception: another instance interception technique. The target types must either be interfaces or classes inheriting from MarshalByRefObject, one instance of which should exist. It is possible to intercept any interface methods or any method declared in the MarshalByRefObject-derived class; the interceptor acts as a proxy between the exposed interface or class and the actual object;
Context-bound object interception: this a .NET-specific interception technique for instance interception by which we can intercept any calls to objects of classes inheriting from ContextBoundObject. This one is not as generic as the others because we need to have our class inherit from ContextBoundObject, which we wouldn’t normally do, and add some boilerplate code.
Next post will talk about static interception.