Thursday, January 27, 2011

Messing around with C# dynamic

At last night’s ALT.NET Vancouver meet up we were talking about the dynamic keyword in C# 4.0 and how it could be used for dispatching a message to the appropriate message handler.  The conversation with a look at Chris Nicola’s blog post on the topic.

The first test that he shows in the post fails. 

[Test]
public void cant_pass_base_class_to_function_dynamically()
{
dynamic handler = new FooMessageHandler();
IMessage message = new FooMessage();
handler.Handle(message);
}

To me, this was expected.  Despite using the dynamic keyword for the message handler, the C# compiler is still going to use the same algorithm for method matching as it does on a static object.  To make this method pass we need to add our own method matching, and in C# dynamic, that means overriding the TryInvokeMember method.


public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = null;

if (binder.Name == "Handle" && args.Length == 1 && args[0].GetType() == typeof(FooMessage))
{
Handle((FooMessage) args[0]);
return true;
}

return false;
}

This code looks to see if the Handle method was being called and then checks if the argument passed in will satisfy the real method then calls then method. It's not the cleanest code, but the test does pass with this override. We can take it a little further and move the method to the base class so that we don't have to repeat the override for each message handler.


public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = null;

if (binder.Name == "Handle" && args.Length == 1 && args[0].GetType() == typeof(T))
{
Handle((T)args[0]);
return true;
}

return false;
}

One of the conclusions that we reached at the meet up was that dynamic is well suited to where reflection would have been used.  I have done message dispatching with reflection in the past and I think I like this approach better once I clean up the code a little more.


P.S. Also check out Cliff Hammerschmidt’s post on Graft-on Visitor in C#.

Friday, January 7, 2011

Inversion of Control: It’s All About Decoupling

I've been using Dependency Injection and Inversion of Control for a few years now and have always wondered why there is such resistance to the concept. I've heard the argument that it seems too complex and on a not-so-recent Dot Net Rocks episode, Richard Campbell was concerned that it would make debugging more difficult. To me, Dependency Injection and Inversion of Control are just fancy words for a technique designed to reduce the coupling in your system.

Coupling is one of those terms that everyone knows, but few pay much attention to on a daily basis. I can remember an exam I wrote for a second year Computer Science course that had the following multiple choice question on it:

Object-oriented code should exhibit these characteristics:

a) High coupling, high cohesion
b) Low coupling, high cohesion
c) High coupling, low cohesion
d) Low coupling, low cohesion

I knew the answer right away, but thinking back on it, I couldn't have gone into much more detail about what those terms actually meant, or more importantly, how to apply the principles to code. I’ve found that coupling and cohesion are concepts that most people take a long time to apply at anything more than an elementary level.

At one place where I used to work, the development team completed 360 degree evaluations of the each other. One of the characteristics that we evaluated each other on was that we wrote “quality object-oriented code that displayed a low level of coupling and a high level of cohesion.” Vague I know, but what was most interesting about it was that the developers who wrote the poorest code in this regard scored themselves the highest, and the developers who wrote the best code, scored themselves the lowest. I interpreted this to mean that the developers who fully understood what it meant to write loosely coupled code were able to remove much of the coupling from their code, but were also keenly aware of the coupling that they left behind.

The argument that IoC makes debugging more difficult doesn’t hold any weight to me.  The argument is that you don’t know exactly which implementation is being called when a method is called because the call is to an interface or an abstract class and not a concrete dependency.  Now listen up people, cause I’m going to let you in on a little secret, THAT’S CALLED LOW COUPLING!  You’re only coupled to the interface, not the implementation, that’s what object orientation is all about!

So the next time someone tries to argue against IoC because it’s too complicated, just remind them about the foundations of object-oriented programming.