Saturday, March 28, 2009

Delegates in Unity - 2

Download: click here

I decided to create my own interception implemented as a UnityContainerExtension. In this post, I'll show how this extension is used to register and intercept delegates. The internals of this extension are discussed in the next post.

To activate the extension, use the following:

container = new UnityContainer();
container.AddNewExtension<DelegateInterceptionExtension>();


Then create your handlers. Here I could have comeup with my own Handler signatures but I decided to use the exisiting ICallHandler from Unity interception. If you're handlers need to be "builtup" then register them with the container. Otherwise, just create new instances and pass those along. If you register them with the container, you can just pass their "alises":

callCounter = new CounterCallHandler();
container.RegisterInstance<ICallHandler>("callCounter", callCounter);


Now you're ready to register your interception. For that I decided to provide one single easy step which registers the delegate instance and also adds its call handlers:

MethodImpl impl = new MethodImpl();
container.Configure<DelegateInterceptionExtension>()
.RegisterDelegate<VoidMethodIntParam>(
impl.VoidMethodIntParamImpl, null, new string[] { "callCounter" }
);


You can now lookup the delegate and call it:

VoidMethodIntParam d = container.Resolve();
d();


My call handler increments a counter everytime it is called. So to show that in fact my call handler was called I assert that the call count is 1:

Assert.AreEqual(1, callCounter.Count);


The implementation of your delegate can be anything from an instance method to a static method to a virtual method to an anonymous method.

When creating anonymous delegates, you can go further and enclose objects from a higher scope in it. In other terms you can create a "closure" over those objects:

container.Configure<DelegateInterceptionExtension>()
.RegisterDelegate<VoidMethod>(
delegate()
{
// here I create a closure:
callCounter.Count += 1;
Trace.WriteLine("Anonymous delegate was called");
},
null,
new string[] { "callCounter" });
VoidMethod d = container.Resolve<VoidMethod>();
d();
Assert.AreEqual(2, callCounter.Count);

No comments:

Post a Comment