Dynamic Proxy Classes
O'Reilly network had an article on uses of dynamic proxies to implement generic memoizing, in Java.
Dynamic proxies are an interesting construct, that appeared in Java 1.3. Here is the JDK documentation for the Proxy class.
Basically, they allow defining a class at runtime that implements any interfaces you want and funnels all its method calls to an InvocationHandler. All the InvocationHandler has to implement the generic Object invoke(Object proxiedObject, Method method, Object args) method.
Java uses of dynamic proxy classes
Proxies can be used for method tracing, as shown here.
Note that only methods are proxied, not member variables (which can't be specified in interfaces anyway). But that means that you don't completely proxy the object and thus can't use a proxy to trace member variable access.
Although the code to add a proxy to a class is really small
(something like IPerson tracePerson = (IPerson)LogProxyFactory.logObject(new Person("Jason", "Bock", 29));), as Jason states, it may be inconvenient. But he doesn't have a solution to avoid it.
Delegates can be emulated thru the use of reflection and dynamic proxy classes. Find it in O'Reilly's "A Java Programmer Looks at C# Delegates".
Although it is interesting to see how it is done, I think the overhead of using this framework just to bridge the "delegates vs. inner class" gap is overkill. Especially since interfaces are still needed for the compile-time type-safety (see scenario 2.). This remains an emulation and feels like one.
I haven't looked at the source yet, but CGLib has an implementation of method delegates. According to Chris it still relies on reflection, but should eventually be switched to runtime byte-code emission via BCEL (Byte Code Engineering Library), for a better invocation performance, traded against a slower creation.
Here are some quick links to other uses of dynamic proxies in Java:
A cleaner way to invoke tests in a JUnit extension: JFunc.
Data type abstraction and access control.
Generic event listeners.
.NET dynamic proxy classes
A dynamic proxy generator or factory can be written in .NET using Reflection.Emit, as described here (sorry, link is in French).
Is there a way to implement a generic memoizing solution in .NET?
I first thought that generics (in C# 2.0 and already available in Rotor and Mono) and delegates should allow for an even cleaner implementation of a re-usable memoizing component. You would make a delegate out of the method you want to memoize and then use a memoizer object using the method's delegate as it's parameterized type.
But trying to lay down the interface for the Memoizer, this seems like a tricky problem. Any suggestions?
Ideally we'd want the Memoizer to take a method delegate and return a memoized delegate. The Memoizer object would hold a cache using the delegate's return type as its parameterized type.
There are two problems:
- how to type parameterize the cache so that it matches the delegates return value type?
- how to have the Memoizer expose and implement a method with the same interface as the delegate?
Type parameterizing the cache
I can think of two approaches for this. Either there should be a way of make a reference to a delegates return type or there should be a way to constrain a delegates return type to match some other type.
For example, the first solution would mean writing Memoizer<DelegateType> and Cache<DelegateType.returnType> map;
The other solution would be having Memoizer<DelegateType, CacheType> memoizer with some way of enforcing that DelegateType's return type would be CacheType. I remember reading somewhere about constraining delegates interfaces, but I couldn't find it again. I'll add it here if I do.
Expose a method with parameterized signature
The problem is to expose and implement a new method with the parameterized DelegateType's signature. A possible solution might be to have something like a runtime-generated dynamic proxy that would match a delegate instead of an interface as we have seen in the case of Java.
This means the Memoizer would implement the InvocationHandler interface and you would write Proxy.newProxyInstance(<DelegateType>, new Memoizer<DelegateType>(origDelegate). All calls to this runtime generated delegate would be funneled (via some JIT trick) to the Memoizer's generic object Invoke(object proxiedObject, MethodInfo method, object params) where it could be handled using reflection.
A set of introductory slides on dynamic proxies in Java.