Third Shelf

Proxy class design

Posted in .net, aop by Sydney du Plooy on April 20, 2008

As part of designing our AOP.NET framework, I thought it best to start with the end in mind. What that entails is to figure out what our proxy class should look like. Let’s start with a simple interface and then design the proxy class according to the interface.

public interface IVehicle
{
  string Make{get;set;}
  void Start();
  void Stop();
}

If only all things in life could be so simple. What do we expect from our proxy class? First of all, it should proxy the call to the target instance.

But before the call is made to the target instance, it should first call our aspect class. Assume, for now, that our aspect just logs an entry whenever a call is made to one of the members.

That means that we would expect our proxy class to look something like this:

[Proxy]
public sealed class IVehicle_LogAspect_Proxy : IVehicle
{
  private IVehicle _TargetInstance;
  private ILoggerAspect _LoggerAspect;

  public IVehicle_LogAspect_Proxy(
    IVehicle targetInstance, ILoggerAspect loggerAspect)
  {
    _TargetInstance = targetInstance;
    _LoggerAspect = loggerAspect;
  }

  public string Make
  {
    get
    {
      _LoggerAspect.Log("Make.Get");
      return _TargetInstance.Make;
    }
    set
    {
      _LoggerAspect.Log("Make.Set");
      _TargetInstance.Make = value;
    }
  }

  public void Start()
  {
    _LoggerAspect.Log("Start");
    _TargetInstance.Start();
  }

  public void Stop()
  {
    _LoggerAspect.Log("Stop");
    _TargetInstance.Stop();
  }
}

First, there is a Proxy attribute applied to the proxy class. This is just to identify the class as a proxy type. Sometimes it might be necessary for calling code to know whether it is dealing with a real object or a proxy. The attribute facilitates this quite nicely.

Naming the type is a matter of concatenating the interface names, separated by underscores together with the aspect that is injected. Finally, we simply just add the word Proxy to the type name to help with identification.

After all that the constructor is next. The constructor plays a vital role in the proxy as it receives the reference to the target instance as well as the reference to the aspect instance. Both these references are assigned to private variables by the constructor.

As you can see, the aspect method is directly injected into the member, before the call is passed to the target instance.

The advantages of doing it this way are that all the heavy aspect code is outside of the proxy class, which makes it a lot simpler to write and maintain.

Now that we have an idea of what the proxy class should look like we will next look at the framework building blocks.

Tagged with: ,

Leave a Reply