I started to familiarize myself with proxy objects a couple of years ago when I started used Fluent NHibernate on a pretty large project. NHibernate itself proxies objects to allow the framework to do its magic. Proxies are a fantastic thing. I spoke with a friend of mine today about some advanced coding techniques including proxy objects and IoC, which made me want to write a little about some of those topics.
From Wikipedia:
A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.
Charles Bretana gave an excellent and succinct definition of proxy objects on Stack Overflow back in 2008:
One purpose is to “pretend” to be the real class so a client component (or object) can “believe” it’s talking to the “real” object, but inside the proxy, other stuff, (like logging, transactional support, etc.) is being done at the same time… Secondly, a proxy can be very cheap in comparson to the real object,. and often is used so that the real objects can be conserved (turned off or released to a pool to be used by other clients) when the client is not using them… The proxy stays “alive” and the client thinks it still has a connection to the real object, but whenever it “calls” the object, it is actually calling the proxy, which goes and gets another real object just to handle the call, and then releases the real object when the call is done.
I’ve created an example (available on github) which demonstrates how to proxy method calls in a few different ways, ranging from very simple to using Castle.DynamicProxy and interceptors. The code is written in C# and although the code doesn’t handle some of the more advanced topics of proxy objects, such as resource pooling as Charles described, it will (I hope) introduce proxy objects in a comprehensible way.
Read on for killer examples.
The Interfaces: IFoo, ILogger
To conserve a little space, I’ll show the interfaces. The actually implementations are simple: the class implementing ILogger accepts a TextWriter in the constructor (Console.Out) and the class implementing IFoo takes an instance of ILogger in the constructor (i.e. manual Dependency Injection).
public interface ILogger {
void Write(string msg);
}
public interface IFoo: ILogger {
ILogger Logger {get;set;}
string ShowBar();
}
The code in the repo can be tested via console application:
ILogger logger = new Logger (Console.Out);
Foo foo = new Foo (logger);
foo.Write ("Testing Foo\n");
// outputs:
// Testing Foo
“Hard-coded” proxies
A proxy is basically any object that “looks” like a target object, but behaves differently. In other words, if I call ShowBar() on the class implementing IFoo, I expect it to only “show bar”. You may however, want to proxy that call and perform some trace logging. This could be handled via a decorator, but the true Decorator Pattern increases the depth of the type’s hierarchy when best practices suggest to keep the hierarchy as shallow as possible. I won’t show an example of the decorator pattern, I just want to warn on the subtlety between the two. Then again, if you create a decorator and call it a proxy, the only people who will care are pedants; if your code works, it works.
To proxy calls to a Foo object, you can create a derived type (FooClassProxy) which proxies the call to the Write method by adding some sort of functionality.
// IFoo foo3 = new FooClassProxy(logger);
public class FooClassProxy : Foo
{
public FooClassProxy (ILogger logger)
: base(logger){}
public override void Write (string msg)
{
base.Write (String.Format("Message: {0}\n", msg));
}
}
This class “is a” Foo object and modifies the implementation of the Write method. Polymorphism can be the simplest form of a proxy object when the base method is the main functionality of the overridden method. If you re-implement the Write method and don’t call base.Write(), you’re not ‘proxying’ anything. Again, this is another subtle difference to be aware of.
Running this code in the repo’s console application doesn’t provide anything too spectacular:
Hard-coded proxy object demonstrating added functionality:
Message: Testing FooClassProxy
A more common reason to proxy objects is to implement trace logging. To demonstrate another way to implement a proxy, I’ve created FooInterfaceProxy which “is a” IFoo, but uses composition (“has a”) internally to encapsulate the implementation of the Foo object.
public class FooInterfaceProxy : IFoo {
private IFoo _foo;
public ILogger Logger {
get;
set;
}
public FooInterfaceProxy(ILogger logger)
{
Logger = logger;
}
public void Write (string msg)
{
Logger.Write("Trace: FooInterfaceProxy.Write enter.");
if(_foo == null) {
Logger.Write("Trace: Creating new Foo");
_foo = new Foo(Logger);
}
_foo.Write(msg);
Logger.Write("Trace: FooInterfaceProxy.Write exit.\n");
}
public string ShowBar() {
if(_foo == null) {
throw new InvalidOperationException("FooBar");
}
return _foo.ShowBar();
}
}
Now, this implementation is relatively similar to the polymorphic example, but we would be less tempted to create a ‘derived’ implementation of the Write method. This implementation is truly creating a proxy to the composite Foo implementation of both Write and ShowBar.
The console output from this example is slightly more interesting because it demonstrates trace logging of the method call and instantiation of the composite object.
Hard-coded proxy object demonstrating trace logging:
Trace: FooInterfaceProxy.Write enter.
Trace: Creating new Foo
Testing FooInterfaceProxy #1
Trace: FooInterfaceProxy.Write exit.
Trace: FooInterfaceProxy.Write enter.
Testing FooInterfaceProxy #2
Trace: FooInterfaceProxy.Write exit.
This is pretty cool, but you wouldn’t want to modify EVERY method to incorporate this trace logging. The answer to this is to use Castle’s DynamicProxy (or a similar framework).
DynamicProxy
From castleproject.org:
You can use DynamicProxy to generate lightweight proxies on the fly for one or more interfaces or even concrete classes (but only virtual methods will be intercepted).
This is pretty much what we’ve been doing manually with the code so far. Suppose, for example, I want to write debug output when every virtual method is executed on a concrete Foo object. I can use an interceptor for this. An Interceptor does exactly as the name suggests: it intercepts a method invocation and adds functionality to it at runtime (hence the name ‘DynamicProxy’).
public class DebugLogger : IInterceptor
{
#region IInterceptor implementation
public void Intercept (IInvocation invocation)
{
Debug.WriteLine("Debug: proxy enter.");
invocation.Proceed();
Debug.WriteLine("Debug: proxy exit.");
}
#endregion
}
Using an interceptor, we can proxy the original Foo object without modifying the code.
Given the original Foo object, we can create the ProxyGenerator and an array of Interceptors to do all of that manual proxy stuff from before… only this time it is done on-the-fly.
The setup:
ILogger logger = new Logger (Console.Out);
Foo foo = new Foo (logger);
var proxify = new ProxyGenerator();
var interceptors = new IInterceptor[] { new DebugLogger() };
Calling CreateClassProxyWithTarget to proxy all virtual methods on the object (1 virtual, 3 non-virtual):
Foo foo4 = proxify.CreateClassProxyWithTarget(foo, interceptors);
foo4.Write("Class Foo proxied dynamically using CreateClassProxyWithTarget");
Console.WriteLine("Calling Class Foo's ToString(): {0}", foo4.ToString());
Console.WriteLine("Calling IFoo.ShowBar(): {0}", foo4.ShowBar());
Console.WriteLine("Calling Foo.ShowBaz(): {0}\n", foo4.ShowBaz());
In the Foo implementation, Write is virtual, while IFoo.ShowBar is not and ShowBaz is a class method (not implementing any interface method). The output for this bit of code will only execute the debug trace for the Write method.
Dynamically proxy an existing object's virtual members (any object works):
Debug: proxy enter.
Class Foo proxied dynamically using CreateClassProxyWithTarget
Debug: proxy exit.
Calling Class Foo's ToString(): Castle.Proxies.FooProxy
Calling IFoo.ShowBar(): Bar
Calling Foo.ShowBaz(): Baz
Suppose, however, that you wanted to intercept all method invocations defined by the IFoo interface. That’s also possible using CreateInterfaceProxyWithTarget of the ProxyGenerator object.
IFoo foo5 = (IFoo)proxify.CreateInterfaceProxyWithTarget(typeof(IFoo), foo, interceptors);
foo5.Write("Class Foo proxied dynamically using CreateInterfaceProxyWithTarget");
Console.WriteLine("Calling Class Foo's ToString(): {0}\n", foo5.ToString());
Console.WriteLine("Calling IFoo.ShowBar(): {0}", foo5.ShowBar());
Now, the output from this bit is possibly the most interesting. You do have the debug trace for both method calls defined on the IFoo interface (2 interface methods, 1 object method):
Dynamic Proxy a specific target:
Debug: proxy enter.
Class Foo proxied dynamically using CreateInterfaceProxyWithTarget
Debug: proxy exit.
Calling Class Foo's ToString(): Castle.Proxies.IFooProxy
Debug: proxy enter.
Debug: proxy exit.
Calling IFoo.ShowBar(): Bar
Notice the order of interception above.
The interesting bit in this last part is that ShowBar() returns a string. Because the parameters to Console.WriteLine are executed before Console.WriteLine is executed, the returned value is stored on the stack between the Debug: proxy exit. line and the Calling IFoo.ShowBar(): Bar line. The call to ToString() is not intercepted because it is not defined on the interface.
Conclusion
Proxy objects are obviously useful. DynamicProxy is useful for use in frameworks like NHibernate, where the framework has no knowledge of the client code which will be consumed and proxied. It transparently allows you to add functionality to the client code. For example, in the last bit of code, I could use IFoo or the Foo object anywhere within my code without knowing (or caring) that it has been proxied.
Some would argue that the added reflection cost is not worth the extra functionality provided by DynamicProxy. I disagree. Having full control over code without the need to modify the existing codebase is well worth the small performance cost. In fact, you can proxy objects for which you don’t have access to the source code.
I definitely suggest checking out the CastleProject frameworks. DynamicProxy is only a small part of what is offered.
Code
In case you missed the link, download the code from github:
https://github.com/jimschubert/blogs/tree/master/2012-07-07/Proxies