3.09.2010

Integrating MEF with a K-means algorithm implementation

When we're interested about a new framework and we want to try it out we usually start by creating a small and simple demo application. Afterwards we start thinking in real-life situations where we could use it. Here, I'll describe my first real-life use of MEF.
I have a small application with a custom implementation of the K-means clustering algorithm. Common implementations of this algorithm attempt to find clusters of points. The cluster points are related by the distance between themselves. In my custom implementation, the points are persons and the "distance" is in fact computed by evaluating a series of constraints. 
Each of these constraints is a distinct class, implementing an IConstraint interface. 
Until know I had the following initialization code for constraints:

Then I had the following code to evaluate the constraints:

Note: In here the "distance" between persons is what I call "concordance rate". The bigger the concordance rate, the "closer" the member is to the cluster.
A few days ago, I had to create a new constraint and when I saw that initialization code and "TODO" comment I decided it was time to change it. After careful thought, I decided MEF was the correct choice. With MEF, I managed to replace this tedious initialization code while reducing the coupling between the concrete constraints and the constraint evaluator.
I've just opened all the Constraint classes and added the attribute [Export(typeof(IConstraint))] like this:

Then I've instructed the ConstraintList property to import all the IConstraints. This is done by marking the property with the attribute [ImportMany(typeof(IConstraint))]. Like this:

Last but not least, I had to instruct the class to compose the constraint list. Like this:

Note that I'm using the using an AssemblyCatalog with the executing assembly on purpose, because I want to load the constraints from the current assembly. If I were to move all the Constraints to another assembly (eg: a separate "Contracts" or "Constraints" assembly) this code would be different.
There you go, just a simple refactoring that allowed me to reduce coupling and remove a TODO comment from my code! And I got to use MEF in a real scenario.

Sem comentários: