Design, Build and Release

Ramblings of IainJMitchell on C#, Javascript and Software Craftsmanship

Archive for the ‘Uncategorized’ Category

Rake copy directory task

leave a comment

A simple, recursive copy directory task for rake:

require 'fileutils'

@source = "./configs"
@target = "./exports"
@includePattern = "/**/*.config"

task :default => [:copyDirectory]

task :copyDirectory do
	FileUtils.rm_rf(@target)  #remove target directory (if exists)
	FileUtils.mkdir_p(@target) #create the target directory
	files = FileList.new().include("#{@source}#{@includePattern}");
	files.each do |file|
		#create target location file string (replace source with target in path)
		targetLocation = file.sub(@source, @target)
		#ensure directory exists
		FileUtils.mkdir_p(File.dirname(targetLocation));
		#copy the file
		FileUtils.cp_r(file, targetLocation)
	end
end

That is all.

Written by IainJMitchell

April 2nd, 2012 at 10:20 am

Posted in Uncategorized

Tagged with ,

Extending classes with IExtensibleObject

leave a comment

Introduction

One of the key features of Windows Communication Foundation (WCF) is the ability to extend various parts of the framework, by adding and/or replacing behaviours. Many of these extension points are implemented by using the IExtensibleObject interface. This post is going to examine how this works and the reasons for using it.

The IExtensibleObject Interface

Classes implement IExtensibleObject in order to be extendible. The interface is defined in .NET as:

namespace System.ServiceModel
{
    public interface IExtensibleObject<T> where T : IExtensibleObject<T>
    {
        IExtensionCollection<T> Extensions { get; }
    }
}

This interface ensures that implementers have a publicly accessible IExtensionCollection, which is the access point for injecting custom behaviour. The example below demonstrates a custom extension being added, via this property, to the InstanceContext in WCF:

  instanceContext.Extensions.Add(customExtension);

The simplest implementation of this interface would look like this:

public class ExtendableClass: IExtensibleObject<ExtendableClass>
    {
        public IExtensionCollection<ExtendableClass> Extensions
          { get; private set; }

        public ExtendableClass()
        {
            this.Extensions =
              new ExtensionCollection<ExtendableClass>(this);
        }
    }

The class adds a setter to the Extensions property, and ensures that the property is initialised during class construction.

Implementing an extension (via IExtension)

In order to be added to the IExtensibleObject.Extensions collection, the class has to implement the generic interface IExtension. This is defined in .NET as:

namespace System.ServiceModel
{
    public interface IExtension<T> where T : IExtensibleObject<T>
    {
        void Attach(T owner);
        void Detach(T owner);
    }
}

Classes that implement this interface will have to define Attach() and Detach() functions. These are called when automatically on an instance, when it is added to a IExtensibleObject.Extensions collection. The owner argument will be the IExtensibleObject class that they are being added to.

Below is a very simple implementation of an extension class for our ExtendableClass. The Attach() and Detach() functions have been implemented simply as console writes.

public class ExtensionClass: IExtension<ExtendableClass>
{
   public void Attach(ExtendableClass owner)
   {
      console.WriteLine("attached!");
   }

   public void Detach(ExtendableClass owner)
   {
      console.WriteLine("detached!");
   }
}

Putting it together

Here is an example of the ExtendableClass and ExtensionClass in action:

var extendable = new ExtendableClass();
var extension = new ExtensionClass();
extendable.Extensions.Add(extension); //writes 'attached!' in console
extendable.Extensions.Clear(); //write 'detached!' in console

So, why would I use this?

The real power of the extensions is the way that they can access the extendible object on the Attach() and Detach() functions. They can then interact with any publicly exposed members on this, without the orchestrating code being aware of it.

Below is a different example of IExtensionObject and IExtension that demonstrate this. The NameExtenable is the extension object, which also holds an internal list of names and methods to add and remove names. There is also a method GetNames() that returns a string of all the names it holds.

public class NameExtendable : IExtensibleObject<NameExtendable>
{
    private readonly List<string> _names = new List<string>();
    public IExtensionCollection<NameExtendable> Extensions
        { get; private set; }

    public NameExtendable()
    {
        this.Extensions = new ExtensionCollection<NameExtendable>(this);
    }

    public void AddName(string name)
    {
        this._names.Add(name);
    }

    public void RemoveName(string name)
    {
        this._names.Remove(name);
    }

    public string GetNames()
    {
        return _names.Aggregate(new StringBuilder(),
            (sb, name) => sb.Append(name),
            sb => sb.ToString());
    }
}

public class IainNameExtension: IExtension<NameExtendable>
{
    public void Attach(NameExtendable owner)
    {
        owner.AddName("Iain");
    }

    public void Detach(NameExtendable owner)
    {
        owner.RemoveName("Iain");
    }
}

public class TerryNameExtension : IExtension<NameExtendable>
{
    public void Attach(NameExtendable owner)
    {
        owner.AddName("Terry");
    }

    public void Detach(NameExtendable owner)
    {
        owner.RemoveName("Terry");
    }
}

The two extension classes (IainNameExtension and TerryNameExtension) use their Attach() and Detach() methods to add and remove a particular names to their owner.

So when we utilise the code, like this…

var nameExtendable = new NameExtendable();
Console.WriteLine("Names: " + nameExtendable.GetNames()); //Names: 

var iainNameExtension = new IainNameExtension();
nameExtendable.Extensions.Add(iainNameExtension);
Console.WriteLine("Names: " + nameExtendable.GetNames()); //Names: Iain

var terryNameExtension = new TerryNameExtension();
nameExtendable.Extensions.Add(terryNameExtension);
Console.WriteLine("Names: " + nameExtendable.GetNames()); //Names: IainTerry

nameExtendable.Extensions.Remove(iainNameExtension);
Console.WriteLine("Names: " + nameExtendable.GetNames()); //Names: Terry

..the resulting console output will resemble:

The code samples from this post are all in this Example solution

Written by IainJMitchell

March 16th, 2012 at 1:16 pm

Posted in Uncategorized

Tagged with ,

Kata exercise: Three is the magic number…

leave a comment

Background

The idea behind “Ping Pong” pairing is that the person driving constantly switches between the pair, so the three stages of Test Driven Development (test, implement and refactor) are carried out in the following pattern:

  1. Person A – Writes a test
  2. Person B – Implements it (to bare minimum)
  3. Person A – Refactors
  4. Person B – Writes a test

…and so on

However, what often happens is that the refactor stage is missed out, which leads to Person A writing all the tests and Person B doing all the implementation! The cause of this is often attributed to an overzealous implementation that is far from the bare minimum, though it can also be just be plain old forgetfulness.

The Kata exercise

Pick any simple Kata (we used the Roman Numerals Kata) and everyone splits into groups of threes, rather than pairs. The three should then tackle the problem with each person taking a TDD role in the cycle – so we end up with the following pattern:

  1. Person A – Writes a test
  2. Person B – Implements it
  3. Person C – Refactors
  4. Person B – Writes a test
  5. Person C – Implements it
  6. Person A – Refactors
  7. Person C – Writes a test

…and so on

The only additional rule is that if the person refactoring has nothing to refactor, then they have to role back to the last written test and start again.

Written by IainJMitchell

February 27th, 2012 at 7:51 pm

Posted in Uncategorized

Tagged with ,

Implementing the Repository pattern with MongoDB and coffeescript/nodejs

one comment

The Repository Pattern is a useful mechanism to abstract the mechanics of the data store away from the business logic. There are various ways of implementing a repository against a relational database, the mechanics could use plain old SQL or something more exotic like nHibernate or Entity Framework.

This post is going to look at constructing a generic repository to use against a mongoDB data store, and because I want to show how ‘hip’ I am, the example will be in coffeescript with nodejs.

Prerequisites

You will need:

  • nodejs & mongoDB installed
  • coffeescript npm package (npm install -g coffee-script)
  • mongojs npm package (npm install -g mongojs)

Implementing Create and Read operations

The first requirement of our repository is that it needs to connect to the mongoDB database, which can be implemented in the classes constructor.

database = "localhost/myDatabase"

class Repository
	constructor: (@objectName) ->
		@db = require("mongojs").connect(database, [@objectName])

Within the constructor, the passed in object name and the database connection string are used to retrieve a connection to the database, that includes the specified objects collection. This connection is stored in the class variable db, so it can be accessed in our repository class operations.
N.B. In the example above the database connection is specified as a variable above the class – it would be much better to read this from a configuration file.

To facilitate the management of domain entities or value objects, repositories need to provide CRUD (Create, Read, Update, Delete) operations on the object. As Javascript is a dynamic language and mongoDB is a document datastore, our code for the write operation will be straightforward:

	add: (value) ->
		@db[@objectName].save(value)

The add method takes in the value to add (the object), it then requests the objects collection from the database connection and saves the object to it. This is the equivalent of calling db.myObject.save({object}) on the mongoDB command line. Alternatively, you could use the .add() method, but unlike the .save() method, this will not save the object if it already exists (by uuid) in the collection.

Implementing the CRUD read operation is also fairly straightforward, certainly much simpler than relational database repositories which require specialised query objects to be passed in and repository strategies to be formulated.

	find: (query, callback) ->
		@db[@objectName].find(query, (err, docs) -> callback(docs))

This .find() method accepts a query object that is passed to the mongojs .find() method, which locates any documents (objects) that match this query. The result is passed back to the caller via the passed in callback function.
N.B. It is also possible to identify and log any errors encountered, using the first (err) argument of the mongojs callback.

The example below demonstrates how the .add() and .find() methods can be used to add objects to the data store, and then search for matching documents.

repository = new Repository("Donkey")

donkey1 = {name: "chris", age: 12}
repository.add(donkey1)

donkey2 = {name: "colin", age: 32}
repository.add(donkey2)

query = {age: 12}
repository.find(query, (donkeys) ->
	console.log donkey for donkey in donkeys
	#expected console output = {name: "chris", age: 12}
)

Updating and Deleting

Now that we have our objects added to the data store, we also need to be able to make amendments to, and delete them. In order to find the records that we want to change, the .update() method must also accept a query object (see below).

	update: (query, value) ->
		@db[@objectName].update(query, {$set: value}, {multi: true})

In addition, to this it also needs to accept the updated value(s), which are encapsulated in the value argument. Both of these are used in the mongojs .update() call executed from within the repository method. The update values are passed as a $set parameter, that ensures that ONLY the fields specified in the value object are updated – none specified fields are left with the value they held prior to the update. It is also worth mentioning that the third argument to mongojs includes a multi property that is set to true – if this is NOT set then only the first matching object will be updated in the collection.

Deleting is much more straightforward, as all our .remove() method needs is a query that specifies the objects that need removing from the collection. So, this can be quite simply implemented as:

	remove: (query) ->
		@db[@objectName].remove(query)

Putting it all together

Our resulting repository code will resemble:

database = "localhost/myDatabase"

class Repository
	constructor: (@objectName) ->
		@db = require("mongojs").connect(database, [@objectName])
	add: (value) ->
		@db[@objectName].save(value)
	find: (query, callback) ->
		@db[@objectName].find(query, (err, docs) -> callback(docs))
	update: (query, value) ->
		@db[@objectName].update(query, {$set: value}, {multi: true})
	remove: (query) ->
		@db[@objectName].remove(query)

exports.Repository = Repository

N.B. The exports is required to make it available in a different file, through the nodejs require command.

Here is an example of all the repository methods being exercised:

repository = new require("./Repository.js").Repository("Donkey")

donkey1 = {name: "chris", age: 12}
repository.add(donkey1)

donkey2 = {name: "colin", age: 32}
repository.add(donkey2)

query = {age: 12}
repository.find(query, (donkeys) ->
	console.log donkey for donkey in donkeys
	#expected console output = {name: "chris", age: 12}
	query2 = {name: "chris"}
	repository.update(query2, {age: 100})
	#chris's age set to 100
	repository.remove(query2)
	#chris removed
)

Conclusion

In this post I have demonstrated how a generic repository can easily be implemented in a dynamic language against a mongoDB database. You may very well be asking that if it is so simple then why bother with the repository at all? I would always argue that the abstraction of the data store is crucial to even the simplest of applications, what if the data suddenly needed to be stored in a different data store? By abstracting the data store logic out, we keep our domain code lean and free of vender specific implementation detail.

UPDATE

This repository implementation is now available on through Node Package Manager (NPM).

npm install mongorepository

Written by IainJMitchell

January 2nd, 2012 at 2:24 pm