Unleashing Attributes with Dynamic Proxy

A flexible way of hooking into attributes is by using a factory method to generate proxies of your entities. In my example I’m going to create a proxy using Dynamic Proxy and then write the name of the method called plus the exact time in milliseconds to the output screen in Visual Studio. The benefit of this is that this functionality does not dirty my entities with non-core detail and makes it easy to apply the functionality in a declarative style.

The Desired Result
By running the following code we can track the exact time between method calls to proxied instances of the class. This gives us a lightweight debugging performance monitor for our application.

[Test]
public void should_print_time_and_message_of_proxy_member_call()
{
var dummy = ProxyFactory.Create<Dummy>();
dummy.Method1();
Thread.Sleep(100);
dummy.Method2();
}

the output from the console should look like this:
Dummy instance accessed. @ 00:38:34.8752500875
Method1 Executed.
Dummy instance accessed. @ 00:38:34.9846250984
Method2 Executed.

The Dummy Class
As you can see the attribute has been applied to our ‘Dummy Class’ with a general message.
[TimeLog("Dummy instance accessed.")]
public class Dummy
{

public virtual void Method1()
{
Debug.WriteLine("Method1 Executed.");
}

public virtual void Method2()
{
Debug.WriteLine("Method2 Executed.");
}
}


Defining the Attribute

public sealed class TimeLoggerAttribute : Attribute
{
private readonly string _message;

public TimeLoggerAttribute(string message)
{
_message = message;
}
}


As you can see our attribute simply allows us to add a message to a type member’s metadata.

Creating the Proxy factory
The proxy factory creates a class proxy of the type passed into it as a type parameter, in our example above it is a class called ‘Dummy’. Note, that in order to create a proxy which is capable of being intercepted you must make the members virtual to allow the proxy to override the implementation of each member:

public class ProxyFactory
{
private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();

public static T Create<T>()
{
return (T)Create(typeof(T));
}

public static object Create(Type type)
{
var proxy = ProxyGenerator.CreateClassProxy(
type, new IInterceptor[] { new TimeLogInterceptor() });
return proxy;
}
}


public class TimeLogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var type = invocation.Proxy.GetType().BaseType;
var attributes = type.GetCustomAttributes(typeof(TimeLogAttribute), false);
var attribute = attributes.FirstOrDefault() as TimeLogAttribute;
if (attribute != null)
{
Debug.WriteLine(string.Format("{0} @ {1}{2}",
attribute.Message, DateTime.Now.TimeOfDay, DateTime.Now.Millisecond));
}
invocation.Proceed();
}
}

The TimeLogInterceptor is doing the real work here, whilst the example given is somewhat fictional, by using attributes and proxies it opens up opportunities for aspect-oriented style programming you may not have attempted before.

Links:
Excellent Multipart Tutorial about Dynamic Proxy by Krzysztof Koźmic.
Castle Project Dynamic Proxy.


Comments

Gravatar # re: Unleashing Attributes with Dynamic Proxy
Posted by aisha on 12/28/2009 11:15 PM
http://www.picktorrent.com

Post Comment

Title *
Name *
Email
Url
Comment *  


Please add 5 and 4 and type the answer here: