DynamicProxy.NET

Last updated the 17. of October 2003

.NET doesn't come with a ready to use Dynamic proxy in the same sense that Java does.
However, there is some Proxy support in .NET, through the Remoting feature, namely the RealProxy class.

DynamicProxy.NET is a wrapper around the RealProxy class and IRemotingInfo interface.
DynamicProxy.NET provides an easy and simple interface to handling proxy invocations, plus it offers support for strict/loose type support (useful for when you cast the proxy to other types than those supported by the object being proxied).

This introduction contains more detailed inners of DynamicProxy.NET. If you wish to read a tutorial to proxies and DynamicProxy.NET click here

Dynamic Proxing

To create a DynamicProxy instance you use the DynamicProxyFactory's CreateProxy() method.
To work with DynamicProxy.NET you need to be aware of a special requirement that DynamicProxy.NET has:

Requirement: DynamicProxy.NET requires your code to use interface based implementation 

What this mean is that you seperate interface and implementation, so you for instance have an interface called ISimpleInterface which defines the methods. You then create a class, for instance called SimpleClass, which implements the interface ISimpleInterface. .NET supports implementing more than one interface and DynamicProxy.NET also supports proxying of more than one interface.

		TestClasses.SimpleClass testClass = new  TestClasses.SimpleClass();
		TestClasses.ISimpleInterface testClassProxy = 
(TestClasses.ISimpleInterface) DynamicProxyFactory.Instance.CreateProxy(testClass, new InvocationDelegate(InvocationHandler));

The InvocationHandler is a InvocationDelegate, which handles the invocation of the proxy in a reflective manner.
The signature for the InvocationDelegate looks like the following:
public delegate object InvocationDelegate(object target, MethodBase method, object [] parameters)

Eample of a Console logging invocation delegate:

		private static object InvocationHandler(object target, MethodBase method, object[] parameters) {
			Console.WriteLine("Before: " + method.Name);
			// Call the real method reflectively



			object result = method.Invoke(target, parameters);
			Console.WriteLine("After: " + method.Name);
			return result;
		}
 		

The InvocationHandler is called everytime a method is called on the proxy object. The InvocationHandler receives three parameters for each invocation:

- target: Which is a reference to the real object being proxied. In this example the target will refer to the SimpleClass instance.
- method: Is the method instance for the method that was called.
- parameters: Is an array containing all the parameters that was given to the method

If for instance the Method4(int inValue) is called is called with the argument 10, the parameters the InvocationHandler() will be:

- target: The SimpleClass instance
- method: An instance of the Method4 reflective method
- parameters: Is an array with one element, which is an integer with the value 10.

To actually call the real method on the SimpleClass you will have to use the reflection API: object result = method.Invoke(target, parameters);

Strict/Loose type support

DynamicProxy.NET also supports both strict and loose type support. Per default the type support is loose. The type support can be specified through the CreateProxy() method in DynamicProxyFactory or via properties on the proxyied object, through the IDynamicProxy interface.

		public object CreateProxy(object target, InvocationDelegate invocationHandler)
		public object CreateProxy(object target, InvocationDelegate invocationHandler, bool strict)
		public object CreateProxy(object target, InvocationDelegate invocationHandler, bool strict, Type[] supportedTypes)
		

If strict is true then each cast is checked for type compliance against the types supported by the proxied object (target ) and the (if specified) list of supportedTypes.
Through the IDynamicProxy interface you can access the following properties

		/// <summary>
		/// Interface for a dynamic proxy. Through this interface you can work on the proxy instance.
		/// </summary>
		public interface IDynamicProxy {
			/// <summary>
			/// The target object for the proxy (aka. the proxied object)
			/// </summary>
			object ProxyTarget {
				get;
				set;
			}

			/// <summary>
			/// The delegate which handles the invocation task in the dynamic proxy
			/// </summary>
			InvocationDelegate InvocationHandler {
				get;
				set;
			}

			/// <summary>
			/// Type support strictness. Used for cast strictness
			/// </summary>
			bool Strict {
				get;
				set;
			}

			/// <summary>
			/// List of supported types for cast strictness support. Is only checked if Strict is true
			/// </summary>
			Type[] SupportedTypes {
				get;
				set;
			}
		}
		

Example

Given the following interface
	/// <summary>
	/// Interface for the SimpleClass (since you have to program against interfaces with the Dynamic proxy)
	/// </summary>
	public interface ISimpleInterface {
		void Method1();
		string Method2();
		int Method3();
		int Method4(int inValue);
		void Method5(int inValue, out int outValue);
		void Method6(ref int value);
	}
		
and a class SimpleClass that implements it
public class SimpleClass : ISimpleInterface
using the InvocationHandler from above, which is a InvocationDelegate delegate, we can proxy a SimpleClass instance in the following way:

    TestClasses.SimpleClass testClass = new TestClasses.SimpleClass();
    TestClasses.ISimpleInterface testClassProxy =  (TestClasses.ISimpleInterface) DynamicProxyFactory.Instance.CreateProxy(testClass, new InvocationDelegate(InvocationHandler));


Notice the use of the ISimpleInterface when coding against the proxy. This is required, since you can't program against the SimpleClass, since it's not an interface and the result from the CreateProxy() is a TransparentProxy which isn't the same same as the SimpleClass.
Therefore: Code against interfaces when you proxy an object

With the proxy instance testClassProxy you can call the methods on the proxied object:

     textClassProxy.Method1()


Using the Invocation handler from above, the call to Method1 on the testClassProxy will first write out some information to the Console, then call the real Method1() on the testClass object.

You can decide exactly what happens during a proxy method call by creating your own InvocationDelegate delegate. This way you could build an Interception framework or even an AOP framework if you wish.

License

LGPL.

Disclaimer:
This software is provided "as is" without warranty of any kind,
either expressed or implied. The entire risk as to the
quality and performance of the software is with you. Should the
software prove defective, you assume the cost of all necessary
servicing, repair, or correction. In no event shall the author,
copyright holder, or any other party who may redistribute the
software be liable to you for damages, including any general,
special, incidental, or consequential damages arising out of
the use or inability to use the software (including, but not
limited to, loss of data, data being rendered inaccurate, loss of
business profits, loss of business information, business
interruptions, loss sustained by you or third parties, or a
failure of the software to operate with any other software) even
if the author, copyright holder, or other party has been advised
of the possibility of such damages.

Download

Compiled for .NET version 1.1. Should work under 1.0 as well.

Binary version:Click here
Binary and Sourcecode version (includes NUnit version 2): Click here

Copyright 2003 Jeppe Cramon