There seems to be much confusion around two kinds of proxies that Castle Dynamic Proxy provides – InterfaceProxyWithTarget and InterfaceProxyWithTargetInterface. On the surface they both appear to be doing the same thing.
Rule of thumb:
If you’re not sure which one you want – you want the one with the longer, confusing name – InterfaceProxyWithTargetInterface.
InterfaceProxyWithTargetInterface seems to be used less often, which is a shame, because what people really want 99% of the time is actually InterfaceProxyWithTargetInterface. However I suppose due to it’s extremely confusing name, and no clear apparent distinction between InterfaceProxyWithTargetInterface and InterfaceProxyWithTarget people tend to pick just the one with shorter name.
Also in previous versions of Dynamic Proxy (up to, and including v2.1) InterfaceProxyWithTargetInterface had some bugs, and had less overloads, which made it less convenient to use than the other one. This is (going to be) greatly improved in version 2.2 (and is available in the trunk now), so there’s really no reason not to use InterfaceProxyWithTargetInterface.
Why’s that? There are two advantages InterfaceProxyWithTargetInterface provides:
- when you use InterfaceProxyWithTargetInterface its invocations will also implement IChangeProxyTarget interface which lets you change the target object that the call will be routed to.
- secondly, and most importantly – InterfaceProxyWithTargetInterface make much better use of cache.
The second one, is actually the most important difference, and as you most of the time won’t care about changing invocation target, you most certainly want to use caching as much as possible. In case of InterfaceProxyWithTargetInterface type of the target object is not taken into account, whereas for InterfaceProxyWithTarget it is. If that’s not clear enough, let’s see that in code:
var proxy1 = generator.CreateInterfaceProxyWithTargetInterface<IOne>(new One());
var proxy2 = generator.CreateInterfaceProxyWithTargetInterface<IOne>(new OneTwo());
var proxy3 = generator.CreateInterfaceProxyWithTarget<IOne>(new One());
var proxy4 = generator.CreateInterfaceProxyWithTarget<IOne>(new OneTwo());