Willkommen | HowTo | Referenzen | Impressum
Kersting it-solutions the sharper way
  # HowTo  


03/17/2004
How to intercept method calls by using a proxy.

This little example shows you how to create a proxy class. By using a proxy class you can easily intercept a call to a certain method. This is useful for example if you want to write information to a logfile or check whether a user is allowed to use that specific method or not.

This code example is great if you want to control what is done with your business objects in detail. However it slows down your code little bit.

Console output will look like this:

--- ProxyExample started ---

before method call...
method called: set_A
after method call...

before method call...
method called: set_B
after method call...

before method call...
method called: Multiply
after method call...

Press any key to quit

Here is the code:


using System;

namespace ProxyExample
{
	class Class1
	{
		[STAThread]
		static void Main(string[] args)
		{
			Console.WriteLine("--- ProxyExample started ---\n");

			Proxy proxy = new Proxy(new BusinessObject());
			BusinessObject bizObject = (BusinessObject)proxy.GetTransparentProxy();

			bizObject.A = 17;
			bizObject.B = 23;
			bizObject.Multiply();

			Console.WriteLine("Press any key to quit");
			Console.ReadLine();
		}
	}
}

using System;

namespace ProxyExample
{
	public class BusinessObject : MarshalByRefObject
	{
		private int a = 0;
		private int b = 0;

		public BusinessObject()
		{
		}

		public int Multiply()
		{
			return a * b;
		}

		public int A
		{
			get { return this.a; }
			set { this.a = value; }
		}

		public int B
		{
			get { return this.b; }
			set { this.b = value; }
		}
	}
}

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

namespace ProxyExample
{
	public class Proxy : RealProxy
	{
		private object target;

		public Proxy(MarshalByRefObject target) : base(target.GetType())
		{
			this.target = target;
		}

		public override IMessage Invoke(IMessage msg)
		{
			IMethodCallMessage call = msg as IMethodCallMessage;

			preprocess();

			Console.WriteLine("method called: " + call.MethodName);
			IMessage returnMsg = RemotingServices.ExecuteMessage(
				(MarshalByRefObject)this.target, call);

			postprocess();

			return returnMsg;
		}

		private void preprocess()
		{
			Console.WriteLine("before method call...");
		}

		private void postprocess()
		{
			Console.WriteLine("after method call...\n");
		}

		public object Target
		{
			get { return this.target; }
			set { this.target = value; }
		}

	}
}