Hendry Luk — Sheep in Fence

May 28, 2008

Roll Your Own COP. Part I: Mixins

Filed under: Software Development — Hendry Luk @ 5:43 am
Tags: ,

A new programming paradigm has been born in distant land of Java. Qi4j introduces the first Composite Oriented Programming (COP) concept to the world, and has drawn massive interest among Java crowd ever since.
It drove me to start a work on implementing Composite Orientation on .Net as a project named Composheep. This will be an open-source lightweight COP framework (as defined by Qi4j) that I will build incrementally as I write each step on this blog as “Roll Your Own COP” series. I publish the project in CodePlex as LGPL.
Let’s start from the mission of COP. One of the biggest flaws of OOP is that it’s not object oriented at all. If anything, OOP is Class-Oriented, since class is the primary citizen that all objects are derived from. Not the other way round.
As an example, I am a programmer at work, a driver in a car, a researcher in kitchen, and a hunter and a pray in the jungle. As an object, my role (class) constantly changes depending on contexts. Some objects also traverses different scope boundaries. For instance, a Person will have its classes changing over time. New abilities are learnt, from Kid, Student, Dancer, Ninja, and he will eventually due, but it doesn’t mean that the Person object should be deleted from the system since the “memory” of him may live for long time. In a conventional OOP system, we will need to transfer some of the states across instances of different classes. In Composite Oriented Programming, they are all ONE instance. We assign role (Class) to an object. Not instantiating objects based on a destined class. Object is therefore the primary citizen of COP. Please visit Qi4j site for more detail.
One of the most important COP concepts is mixin, in which multiple reusable classes are mixed to form a solid composite. It relies much on Java class generation technique, in which .net is always known far inferior. But, as the first part of the series, I will show how easy it actually is to build our own Mixins implementation on .net using Castle DynamicProxy, in only 15 minutes.
Our objective is to achieve a robust Mixins builder that is smart enough to:
– Handle both properties and methods
– Differentiate parameters overload. E.g. foo() and foo(string)
– Handle generic methods. E.g. foo<T>()
– Differentiate generics overload. E.g. foo<T>() and foo<T,Y>()
– Declarative programming using attributes
As a sample use-case, first I will define a composite of Person that is composed from 2 mixins: HasName and CanFight. I want to define the composite in the following fashion:

[Mixin(typeof(HasNameImpl), typeof(Fighter))]
public interface Person: HasName, CanFight
{
}

Note that Person, as a composite, is defined as an interface. We won’t write any implementation of Person since it will be automatically derived by composing 2 mixin implementations together. We declaratively specify that we wish to use HasNameImpl and Fighter as mixin implementor by using Mixin attribute.
Here is the definition of the mixins:

public interface HasName
{
	string FirstName{ get; set;}
	string LastName { get; set;}

	string IntroduceSelf();
	string IntroduceSelf(string target);
}

public interface CanFight
{
	string Kick<Target>();
	string Kick<LTarget, RTarget>();
}

And the following is the implementation of each mixins:

public class HasNameImpl: HasName
{
	public string FirstName {get; set;}
	public string LastName {get; set;}

	public string IntroduceSelf()
	{
		return Console.Writeln(
			"Hi there, I am {0} {1}",
			FirstName, LastName);
	}

	public string IntroduceSelf(string target)
	{
		return Console.Writeln(
			"Hi {0}, I am {1} {2}",
			target, FirstName, LastName);
	}
}

public class Fighter: CanFight
{
	public string Kick<Target>()
	{
		return Console.Writeln
			("Roundhouse kick to {0}",
		typeof (Target).Name);
	}

	public string Kick<LTarget, RTarget>()
	{
		return Console.Writeln
			("Left foot to {0}, and right foot to {1}",
		typeof (LTarget).Name,
		typeof (RTarget).Name);
	}
}

The following is how I want the client code to be:

CompositeBuilder builder = new CompositeBuilder();
Person person = builder.BuildComposite<Person>();

person.FirstName = "Hendry";
person.LastName = "Luk";
person.IntroduceSelf());
person.IntroduceSelf("Goofy"));
person.Kick<Dog>());
person.Kick<Dog, DebtCollector>());

We instantiate an object of Person, whose implementation is generated dynamically by mixing HasNameImpl and Fighter together to form a complete Person. This way, we will be able to separate a class into smaller chunks of fragment (mixin) that can be reused effectively.
I think this use simple use-case provides a good coverage to all our 5 requirements. It exploits the use of properties, methods with overloaded parameters, and methods with overloaded generics.
Now, to make this work, we will need to write the CompositeBuilder as part of our Composheep solution. We will be using Castle DynamicProxy, which is a lightweight proxy generator used in many open-source frameworks like nHibernate, Windsor, Aspect#, etc.
Here is the implementation of CompositeBuilder. It searches for MixinAttributes in supplied type, then grab the mixin implementer types that was provided as attribute parameter.

public class CompositeBuilder
{
	private ProxyGenerator generator = new ProxyGenerator();

	public T BuildComposite<T>() where T : class
	{
		CompositeInterceptor interceptor = new CompositeInterceptor();

		object[] attributes =
		typeof(T).GetCustomAttributes(typeof(MixinAttribute), true);
		foreach (MixinAttribute mixin in attributes)
		{
			foreach (Type mixinType in mixin.Types)
				interceptor.AddMixin(Activator.CreateInstance(mixinType));
		}

		return generator.CreateInterfaceProxyWithoutTarget(interceptor);
	}
}

ProxyGenerator is an API from Castle DynamicProxy that we use to dynamically define implementation of composite interface. The most important part of this only method is that in each mixin type defined in mixin attribute, we use default constructor to instantiate the mixin, and pass it to CompositeInterceptor. It’s a custom proxy interceptor that we will create to handle each composite method invocation to its corresponding mixin implementation.
Here is the code for CompositeInterceptor.

internal class CompositeInterceptor : IInterceptor
{
	Dictionary methodTargetMap =
		new Dictionary();

	public void AddMixin(object mixin)
	{
		Type targetType = mixin.GetType();

		MethodInfo[] methods =
		targetType.GetMethods(
		BindingFlags.Instance |
		BindingFlags.Public |
		BindingFlags.NonPublic);

		foreach(MethodInfo method in methods)
		{
			// Skip members declared in System.Object
			if (method.DeclaringType == typeof(object))
				continue;

			methodTargetMap.Add(method.ToString(), mixin);
		}
	}

	// Implementing IInterceptor.Intercept method
	public void Intercept(IInvocation invocation)
	{
		object target = FindMixin(invocation.Method);
		if (target == null)
			throw (new NotImplementedException());

		invocation.ReturnValue =
		invocation.Method.Invoke(
		target, invocation.Arguments);
	}

	private object FindMixin(MethodInfo callMethod)
	{
		if (callMethod.IsGenericMethod)
			callMethod = callMethod.GetGenericMethodDefinition();

		foreach (String method in methodTargetMap.Keys)
		{
			if (method == callMethod.ToString())

				return methodTargetMap[method];
		}
		return null;
	}
}

The idea is that AddMixin method will map each method signature with a mixin instance in a Dictionary. Therefore, when we intercept a proxy method invocation, we will be able to lookup the dictionary for the method signature, and get the mixin instance. Finally, the invocation will be redirected to that mixin instance.
The easiest way to lookup matching method signature (in FindMixin method) is by using MethodInfo.ToString() since it gives us the method name, parameters types, return type, and generic parameters. So we will be using this as the key of the Dictionary as well.
The only problem with generic parameter is that we will be storing open-generic method signature, for example, string Kick() in AddMethod method during interface introspection. But during invocation, we will get passed with a closed-generic method, for instance, string Kick(). To get around this, we put 2 lines on top of FindMixin:

if (callMethod.IsGenericMethod)
callMethod = callMethod.GetGenericMethodDefinition();

It converts void Kick() back into void Kick(). And this is all we need to build our mixin builder! Run the application, and this is what we got:

Just few minutes of pretty straightforward code and we’ve got the building block for our Composheep in place. You can download the code for this episode here. Coming next, in the second episode, we will be building the second features of COP: concerns and side-effects.

About these ads

8 Comments »

  1. Nice work, looking forward to upcoming episodes. Have you thought about placing the sourcecode on codeplex or somewhere similar?

    Cheers,

    Andreas

    Comment by Andreas Hallberg — June 5, 2008 @ 7:33 am | Reply

  2. I put the source code in codeplex at http://www.codeplex.com/Composheep/.
    Although it’s still fairly basic and has zero code coverage.

    Comment by hendryluk — June 5, 2008 @ 11:41 pm | Reply

  3. I just realised that WordPress had stripped out all the generics constructs from the source code for some reason. I just fixed that, and things should start to make sense now ;)

    Comment by hendryluk — June 6, 2008 @ 12:16 am | Reply

  4. [...] start with the second instalment of “Roll Your Own COP” saga. If you haven’t read the first episode of this series, I recommend you to do so. And if you haven’t heard of Composite Oriented Programming at all, you [...]

    Pingback by Roll Your Own COP, Part 2: Concern and SideEffect « Hendry Luk — Sheep Beyond the Fence — June 9, 2008 @ 10:00 am | Reply

  5. MVVM – Creating ViewModel : create dynamic proxies with Castle (solution 3 of n)…

    Here is the next episode of our serie MVVM – Creating ViewModel. A list of all the article about creating a ViewModel is here.. Today we are going to see how to create dynamic proxies for our business objects. What are Dynamic proxies ? Readers in a…

    Trackback by Yet another blog about : WPF, Surface, Win 7, NUI.... — March 12, 2010 @ 10:55 am | Reply

  6. Thx for this article !

    Comment by Jmix90 — March 12, 2010 @ 10:56 am | Reply

  7. Why did you stop work on this? It looked promising.

    Comment by A'braham Barakhyahu (@BlessYahu) — November 29, 2011 @ 5:16 pm | Reply

    • Thanks for looking at the project.

      I stopped mainly because I stopped working on .Net at that time ;)
      I’ve been back to .net again recently, but recent changes in the technologies (specifically lambda-expressions, extension-methods, DLR, MEF, and my own other project: SheepAspect) have dramatically affect the problem-space that COP tried to solve. Assuming COP is still relevant, the implementation will have to be revisitted and redesigned to fit today’s .net.

      Also I’ve been thinking about the fundamental question: if I need COP in .net, shouldn’t I just go ahead and use .net languages that natively supports it (e.g. DLR, Boo)? Rather than trying to bend C# to look like DLR.

      I’m interested to hear any thoughts and ideas though.

      Comment by Hendry Luk — November 29, 2011 @ 11:33 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: