Classes and instances…what gives!

My brother, who is a DevOps and integrations whizz, got around to quizzing me, after hearing chatter amongst the nearby developer folk in his building, about the wonderful world of classes and instances, as they pertain to C#.

I reeled off the best explanation I could as I sipped on the best damn gin ever (actually, voted the UK’s best, check this out) and scoffed down some superb steak and chips. I didn’t think my musings were all that bad, but I got to thinking that formalising and solidify my thoughts on the matter wouldn’t hurt. Last aside, if you’re in Norfolk and fancy a good meal this is worth hitting up:

The Boars Spooner Row

What is a steak…I mean, class!?

Food on the brain! Ok, in layman’s terms, a class simply defines a template or blueprint for anything being represented in a given computer program. This blueprint contains (but doesn’t have to and is not limited to), on a basic level, properties that describe the thing being templated and methods that represent actions or functions (that may or may not receive external stimuli, or variables) the, for want of a better term, thing can perform. The class, in and of itself, does nothing up until the point it is brought into life…meaning when an instance is created (ignoring static classes, for the purposes of this explanation).

So, what is an instance?

Instances, typically, are brought to life for actual use, in C#, using the new keyword and all we are doing here is bringing an occurrence (to try and avoid typing instance, again) of a given blueprint into being so the descriptive values of the object can be accessed and the functionality triggered.

I would normally use the tried and tested example of vehicles to show how this actually works, with a little dip into inheritance to boot, but I’m going off piste with the first thing that came into my head…different types of homes is what I’m going with.

Let’s start with a blueprint (or class) for a Home. I don’t want this to be too complicated but going too trivial may not get the key points across, so hopefully this middle ground will make sense:

/// <summary>
/// The blueprint, in our application, for a place
/// to live.
/// </summary>
public class Home
{
	#region Private Readonly Data Fields

	/// <summary>
	/// Every home is expected to have rooms. This value, as it's marked
	/// as readonly, can only be set with a value here as part of the declaration or
	/// as part of a 'constructor' (that is involved in building an instance of a home) - in this 
	/// first iteration the number of rooms in a home isn't going to change (we'll come back to this!).
	/// </summary>
	private readonly int numberOfRooms;

	#endregion Private Readonly Data Fields

	#region Private Data Fields

	/// <summary>
	/// A private variable that keeps track of whether the 
	/// door to the home is open or closed. The door to a home
	/// can only be opened/closed by triggering the OpenDoor/CloseDoor
	/// methods on an 'instance' of the type, no direct 
	/// access is allowed = encapsulation.
	/// </summary>
	private bool doorOpen = false;

	#endregion Private Data Fields

	#region Public Properties

	/// <summary>
	/// Allow an object user to get a value representing if a home's
	/// door is open or closed, without allowing them to directly 
	/// change the state of the door.
	/// </summary>
	public bool IsDoorOpen
	{
		get
		{
			return doorOpen;
		}
	}

	/// <summary>
	/// Much like with IsDoorOpen, allow an object user to get a 
	/// readout of the number of rooms in this home without any direct
	/// access to change it at this point (and the underlying variable
	/// is currently readonly anyway, disallowing changes at this time).
	/// </summary>
	public int NumberOfRooms
	{
		get
		{
			return numberOfRooms;
		}
	}

	#endregion Public Properties

	#region Constructor

	/// <summary>
	/// The 'constructor' for a Home that is used to setup object
	/// state for each and every instance of a home.
	/// </summary>
	/// <param name="roomCount">The number of rooms that are in this house (provided by the object user).</param>
	public Home(int roomCount)
	{
		numberOfRooms = roomCount;
	}

	#endregion Constructor

	#region Public Methods

	/// <summary>
	/// Public method that triggers an action on this home, i.e. opens
	/// the door of this home.
	/// </summary>
	public void OpenDoor()
	{
		// Opens the door to the house
		doorOpen = true;

		// Perhaps other things happen as a result of this...
		Console.WriteLine("The door on this home has been opened.");
	}

	/// <summary>
	/// Public method that triggers an action on this home, i.e. closes
	/// the door of this home. 
	/// </summary>
	public void CloseDoor()
	{
		// Closes the door to the house
		doorOpen = false;

		// Perhaps other things happen a result of this...
		Console.WriteLine("The door on this home has been closed.");
	}

	#endregion Public Methods
}

I’ve outlined the starting concept of what I think a ‘Home’ looks and feels like. A home has, from my very barebones view (forgetting about things like walls, ahem!):

  • A number of rooms.
  • A door.
  • A way for the door to be opened and closed.

Obviously, homes are far more complicated than this, but this will get us going. Regardless of the keywords and definitions used this is nothing more than a blueprint, an instance of an object is required to start interacting with a home, as follows:

        /// Create an instance of a home, using the blueprint provided, and open
        /// then close the door (as well as read out the number of rooms).
        /// </summary>
        private static void PlayWithAHome()
        {
            // Use the 'Home' class blueprint to create an 'instance' of a Home so we can actually start reading/triggering facets of it
            // The Home blueprint demands, in this case, that we provide the number or rooms (as part of the constructor)
            Home testHome = new Home(6);

            // Let's use our home...
            Console.WriteLine($"The home has { testHome.NumberOfRooms } rooms.");               // How many rooms does the home have
            Console.WriteLine($"The door is { (testHome.IsDoorOpen ? "open" : "closed") }.");   // Is the door open or closed (should start closed)

            // Let's open the door (we should get a console readout as part of triggering this functionality on a Home)
            testHome.OpenDoor();

            Console.WriteLine($"The door is now { (testHome.IsDoorOpen ? "open" : "closed") }.");   // Is the door open or closed (should now be open)

            // Stop the application so we can read the output
            Console.Read();
        }
Home object being used.

Home object being used.

A simple run through then; a home has a blueprint that defines it will contain a certain number of rooms, a door, a way to read out the number of rooms and whether the door is ajar (private fields and properties) and a mechanism for opening and closing the door (methods). This is the class (or type). To actually get a readout on the number of rooms and start opening and closing the door we need to build the home, end of; this is the instance.

There are a few extra comments in the Home class that discuss ‘readonly’ variables, ‘getter only’ properties (which ties in encapsulation) and the constructor; I’ll leave you to peruse them as I’ve covered the meat of classes and instances at this point.

Sideline question…how does inheritance come into this

Just before my poor Mum looked destined to snooze off at the dinner table, meaning for everyone’s sanity the subject had to be changed, we also skimmed inheritance; so I’ll give one brief example below using our ‘Home’ class from before (modified to make it simpler this time around).

Inheritance, in short, is the idea of building a ‘chain’ of related classes, by building common functionality into a ‘base’ class and then reusing/overriding this functionality in one or more sub-classes; basically, new classes can be created using an existing class as a starting point. The core concept behind classical inheritance is the ‘is a’ relationship between types; below we have a one man tent, bungalow and house; these can all be prefixed with the term ‘is a’ to establish a valid sounding relationship (a house ‘is a’ home, for example).

Firstly, although not required for inheritance, I’ve created an interface, or contract, that outlines the common functionality that any implementing class must define (and subsequently, will be tied to subclasses). This wasn’t mandatory for the example I was putting together but I’ve opted to roll with it.

namespace HomeApplication
{
    /// <summary>
    /// Public interface that defines the properties and behaviours
    /// that all homes should exhibit. The Home class will use this interface
    /// that basically states that the class will implement the described properties/methods - 
    /// This can be thought of as a contract (a promise that the facets will be found on the class).
    /// </summary>
    public interface IHome
    {
        /// <summary>
        /// Homes all have a certain number of floors, or living 'levels'.
        /// </summary>
        int NumberOfFloors { get; }

        /// <summary>
        /// Homes all have a certain number of rooms.
        /// </summary>
        int NumberOfRooms { get; }

        /// <summary>
        /// Homes all have a way to tell if the door is open or closed.
        /// </summary>
        bool IsDoorOpen { get; }

        /// <summary>
        /// Homes (for my example) are expected to have a way to open the door.
        /// </summary>
        void OpenDoor();

        /// <summary>
        /// Homes (for my example) are expected to have a way to close the door.
        /// </summary>
        void CloseDoor();

        /// <summary>
        /// Homes (for my example) are expected to have a way to turn on the heating.
        /// </summary>
        void TurnOnHeating();
    }
}

Using our IHome interface, the Home class outlines common functionality and properties to be shared by all subclasses; we are ultimately just using, as stated before, this class as a starting point to create other classes.

This class has been listed as abstract (which is not a requirement for implementing inheritance), which means that a ‘Home’ is an abstract concept only and I want to disallow users from creating an instance of this type; only instances of subclasses should be created. In as short a description as possible, virtual members provide a default implementation but can be optionally overridden by subclasses, abstract members, however, require subclasses to provide the full implementation (we are simply stating, in this case, that subclasses should implement a particular flavour of functionality). Other than that, I’ve described other pertinent details in the comments within the class definition itself.

using System;

namespace HomeApplication
{
    /// <summary>
    /// The blueprint, in our application, for a place
    /// to live. This is 'abstract', meaning no one can create
    /// a home as an instance to use directly, they can only create
    /// sub-classes of 'Home' for use in an application.
    /// </summary>
    public abstract class Home : IHome      // IHome defines a contract that 'Home' has to conform to (and therefore, that all sub-classes will be locked in to)
    {
        #region Public Properties

        /// <summary>
        /// Allow an object user to read the number of floors
        /// in this home (this value can only be set privately
        /// within this class, not from another class or sub-class directly).
        /// </summary>
        public int NumberOfFloors { get; private set; }

        /// <summary>
        /// Allow an object user to read the number of rooms
        /// in this home (this value can only be set privately
        /// within this class, not from another class or sub-class directly).
        /// </summary>
        public int NumberOfRooms { get; private set; }

        #endregion Public Properties

        #region Public Virtual Properties

        /// <summary>
        /// Allow an object user to obtain a value that represents if
        /// the door is open or closed. This is virtual as I want to allow
        /// derived types to optionally override how this is determined.
        /// </summary>
        public virtual bool IsDoorOpen { get; private set; }

        #endregion Public Virtual Properties

        #region Constructor

        /// <summary>
        /// When an 'instance' of a home is created we expect
        /// to be provided with the number of floors and rooms
        /// available within the home.
        /// </summary>
        /// <param name="floors">The default number of floors on offer.</param>
        /// <param name="rooms">The default number of rooms on offer.</param>
        public Home(int floors, int rooms)
        {
            // Store the provided values in the appropriate properties
            NumberOfFloors = floors;
            NumberOfRooms = rooms;
        }

        #endregion Constructor

        #region Protected Methods

        /// <summary>
        /// Protected members or only accessible from within this type and from direct
        /// descendant types, not from an external class. I want sub-types to possibly alter
        /// how many rooms (by adding a room) can be found in the home.
        /// </summary>
        /// <param name="numberOfRooms">The number of rooms to add.</param>
        protected void AddExtraRooms(int numberOfRooms)
        {
            NumberOfRooms += numberOfRooms;
        }

        #endregion Protected Methods

        #region Public Virtual Methods

        /// <summary>
        /// Public virtual method that closes a home's door - this represents
        /// the 'default' implementation only. This is virtual as I want derived 
        /// classes to be able to optionally override how this process 
        /// happens (see the OneManTent, for example).
        /// </summary>
        public virtual void CloseDoor()
        {
            // Closes the door to the house (enhanced to fully use auto properties)
            IsDoorOpen = false;

            // Perhaps other things happen a result of this...
            Console.WriteLine("The door on this home has been closed.");
        }


        /// <summary>
        /// Public virtual method that opens a home's door - this represents
        /// the 'default' implementation only. This is virtual as I want derived 
        /// classes to be able to optionally override how this process 
        /// happens (see the OneManTent, for example).
        /// </summary>
        public virtual void OpenDoor()
        {
            // Opens the door to the house (enhanced to fully use auto properties)
            IsDoorOpen = true;

            // Perhaps other things happen as a result of this...
            Console.WriteLine("The door on this home has been opened.");
        }

        #endregion Public Virtual Methods

        #region Public Abstract Methods

        /// <summary>
        /// Final method...this is abstract as we are enforcing a situation whereby derived
        /// types of 'Home' have to implement this themselves (every home's method of heating will
        /// vary in my test setup) - there is no default implementation.
        /// </summary>
        public abstract void TurnOnHeating();

        #endregion Public Abstract Methods
    }
}

Our other classes are utilising inheritance directly, using the Home class as a ‘template’ and using ‘overrides’ where applicable to provide their own spin on functionality, as required.

For example, all types support opening and closing of the door; however, tents override this functionality to take the ‘zip getting stuck’ into account. Houses allow for extensions to be built, which ultimately means that further rooms get added to the home. Further in line comments are there for more in-depth explanations as to what is going on.

using System;

namespace HomeApplication
{
    /// <summary>
    /// Blueprint that defines what a house looks like
    /// (this 'is a' home in my example).
    /// </summary>
    public class House : Home       // A house 'is a' home, but has some differences, which this class outlines
    {
        #region Constructor

        /// <summary>
        /// The constructor for a house consumes values that represent
        /// the number of floors and rooms that are available - these are passed
        /// directly to the Home base classes constructor.
        /// </summary>
        /// <param name="floors">The default number of floors on offer.</param>
        /// <param name="rooms">The default number of rooms on offer.</param>
        public House(int floors, int rooms) 
            : base(floors, rooms)
        {

        }

        #endregion Constructor

        #region Public Methods

        /// <summary>
        /// This method is house specific, in my example (could apply to a bungalow, of course, but
        /// I've opted to not allow this for now). A house can have an extension added by calling the protected
        /// (only accessible from the Home class or derived types, like this 'House') AddExtraRooms method. The room
        /// count for this House will therefore be increased by one.
        /// </summary>
        public void AddAnExtension()
        {
            Console.WriteLine("Adding an extension to the house (+1 rooms).");
            AddExtraRooms(1);
        }

        #endregion Public Methods

        #region Public Overridden Methods

        /// <summary>
        /// This represents what happens when the heating is turned on in a house 
        /// (remember, this was marked as abstract on the base class so this class
        /// has no choice but to offer up some kind of implementation). Super toasty
        /// central heating is on offer here!
        /// </summary>
        public override void TurnOnHeating()
        {
            Console.WriteLine("Turning on the central heating in the house.");
        }

        #endregion Public Overriden Methods
    }
}
using System;

namespace HomeApplication
{
    /// <summary>
    /// Blueprint that defines what a bungalow looks like
    /// (this 'is a' home in my example).
    /// </summary>
    public class Bungalow : Home        // A bungalow 'is a' home, but has some differences, which this class outlines
    {
        #region Constructor

        /// <summary>
        /// The constructor for a bungalow consumes a value that represent
        /// the number of rooms that are available - this is passed
        /// directly to the Home base classes constructor. Notice that we are internally
        /// setting the amount of floors to 1 (illustration only, to show how a derived type
        /// can take control of it's own state).
        /// </summary>
        /// <param name="rooms">The default number of rooms on offer.</param>
        public Bungalow(int rooms) 
            : base(1, rooms)            // Bungalows - we only allow a single floor in our example
        {

        }

        #endregion Constructor

        #region Public Overridden Methods

        /// <summary>
        /// This represents what happens when the heating is turned on in a bungalow 
        /// (remember, this was marked as abstract on the base class so this class
        /// has no choice but to offer up some kind of implementation). A Coal fire
        /// have been selected as the weapon of choice in this case.
        /// </summary>
        public override void TurnOnHeating()
        {
            Console.WriteLine("Lighting up the coal fire in the bungalow.");
        }

        #endregion Public Overriden Methods
    }
}
using System;

namespace HomeApplication
{
    /// <summary>
    /// Blueprint that defines what a one man tent looks like
    /// (this 'is a' home in my example).
    /// </summary>
    public class OneManTent : Home      // A one man tent 'is a' home, but has some differences, which this class outlines
    {
        #region Public Properties

        /// <summary>
        /// The door for a tent has an added element to worry about...the bloody zip!
        /// If the zip is broken the door (in my example) is classed as stuck open, might not
        /// be true to reality but serves as illustrative only.
        /// </summary>
        public bool IsZipBroken { get; set; }

        #endregion Public Properties

        #region Public Overridden Properties

        /// <summary>
        /// Overriden functionality from the 'Home' base class. If the zip is broken
        /// the door is classed as open. If the zip isn't broken we simply read if the door
        /// is open or closed from the base class.
        /// </summary>
        public override bool IsDoorOpen
        {
            get
            {
                return IsZipBroken ? true : base.IsDoorOpen;
            }
        }

        #endregion Public Overridden Properties

        #region Constructor

        /// <summary>
        /// The constructor for a one man tent consumes a value that represent
        /// the number of rooms that are available - this is passed
        /// directly to the Home base classes constructor. Notice that we are internally
        /// setting the amount of floors to 1 (illustration only, to show how a derived type
        /// can take control of it's own state).
        /// </summary>
        /// <param name="rooms">The default number of rooms on offer.</param>
        public OneManTent(int rooms) 
            : base(1, rooms)                // Tents - we only allow a single floor in our example
        {

        }

        #endregion Constructor

        #region Public Overridden Methods

        /// <summary>
        /// A tent overrides how a the door is opened. If the zip is broken the tent
        /// door is stuck open. Otherwise, the door opens as normal (via functionality
        /// found on the 'base' class).
        /// </summary>
        public override void OpenDoor()
        {
            if (!IsZipBroken)
            {
                // Zip is not stuck, open the door as normal
                base.OpenDoor();
            }
            else
            {
                // The zip is stuck!!!
                Console.WriteLine("The zip is broken so the tent door is stuck open");
            }
        }

        /// <summary>
        /// A tent overrides how a the door is closed. If the zip is broken the tent
        /// door is stuck open. Otherwise, the door opens as normal (via functionality
        /// found on the 'base' class).
        /// </summary>
        public override void CloseDoor()
        {
            if (!IsZipBroken)
            {
                // Zip is not stuck, close the door as normal
                base.CloseDoor();
            }
            else
            {
                // The zip is stuck!!!
                Console.WriteLine("The zip is broken so the tent door is stuck open");
            }
        }

        /// <summary>
        /// This represents what happens when the heating is turned on in a one man
        /// tent (remember, this was marked as abstract on the base class so this class
        /// has no choice but to offer up some kind of implementation). Hot water bottles
        /// are the only choice here!
        /// </summary>
        public override void TurnOnHeating()
        {
            Console.WriteLine("Urm...using the hotwater bottle for extra heat!");
        }

        #endregion Public Overriden Methods
    }
}
/// <summary>
/// Further fun and games with homes!
/// </summary>
private static void PlayWithHomes()
{
	// A House, Bungalow and OneManTent are 'Homes', therefore share some of the blueprint information (as they are derived classes). Let's use them, and explore the differences

	// Configure instances, with floor and room numbers, as available to us
	House myHouse = new House(2, 8);
	Bungalow myBungalow = new Bungalow(7);
	OneManTent myTent = new OneManTent(2);

	// 1) The House...
	Console.WriteLine("Details about myHouse..." + Environment.NewLine);
	Console.WriteLine($"The house has { myHouse.NumberOfRooms } rooms.");
	Console.WriteLine($"The house has { myHouse.NumberOfFloors } floors.");
	Console.WriteLine($"The house door is { (myHouse.IsDoorOpen ? "open" : "closed") }.");

	// Open the door and check the door state
	myHouse.OpenDoor();
	Console.WriteLine($"The house door is { (myHouse.IsDoorOpen ? "open" : "closed") }.");

	// Turn on the heating in the house
	myHouse.TurnOnHeating();

	// Add an extension (house specific)
	myHouse.AddAnExtension();
	Console.WriteLine($"The house has { myHouse.NumberOfRooms } rooms (after adding an extension)." + Environment.NewLine);

	// ---------------------------------------------------------------------------------------------------

	// 2) The Bungalow...
	Console.WriteLine("Details about myBungalow..." + Environment.NewLine);
	Console.WriteLine($"The bungalow has { myBungalow.NumberOfRooms } rooms.");
	Console.WriteLine($"The bungalow has { myBungalow.NumberOfFloors } floor.");
	Console.WriteLine($"The bungalow door is { (myBungalow.IsDoorOpen ? "open" : "closed") }.");

	// Open the door and check the door state
	myBungalow.OpenDoor();
	Console.WriteLine($"The bungalow door is { (myBungalow.IsDoorOpen ? "open" : "closed") }.");

	// And close it this time, for good measure
	myBungalow.CloseDoor();
	Console.WriteLine($"The bungalow door is { (myBungalow.IsDoorOpen ? "open" : "closed") }.");

	// Turn on the heating in the bungalow
	myBungalow.TurnOnHeating();

	Console.WriteLine();

	// ---------------------------------------------------------------------------------------------------

	// 3) The One Man Tent...
	Console.WriteLine("Details about myTent..." + Environment.NewLine);
	Console.WriteLine($"The tent has { myTent.NumberOfRooms } rooms.");
	Console.WriteLine($"The tent has { myTent.NumberOfFloors } floor.");
	Console.WriteLine($"The tent door is { (myTent.IsDoorOpen ? "open" : "closed") }.");

	// Let's break the zip!
	myTent.IsZipBroken = true;

	// Open the door and check the door state (it should be stuck open)
	myTent.OpenDoor();
	Console.WriteLine($"The tent door is { (myTent.IsDoorOpen ? "open" : "closed") }.");

	// And close it this time, for good measure
	myTent.CloseDoor();
	Console.WriteLine($"The tent door is { (myTent.IsDoorOpen ? "open" : "closed") }.");

	// Fix the zip and try to re-open and close the door
	myTent.IsZipBroken = false;

	myTent.OpenDoor();
	Console.WriteLine($"The tent door is { (myTent.IsDoorOpen ? "open" : "closed") }.");

	myTent.CloseDoor();
	Console.WriteLine($"The tent door is { (myTent.IsDoorOpen ? "open" : "closed") }.");

	// Turn on the heating in the tent
	myTent.TurnOnHeating();

	// Stop the application so we can read the output
	Console.Read();
}

Finally, the following diagram shows that tents, bungalows and houses ‘are’ homes; they share the common facets of a home whilst providing their own functionality and overridden logic, that’s essentially it!

Home class diagram.

Home class diagram.

Home instances output.

Home instances output.

I’ll do a more in depth OOP principle post in the future so watch this space.

Happy Easter!!!

LINQ Joins – Multiple Match Conditions

Hi all,

Just a very quick post on an interesting piece of LINQ knowledge demonstrating how to find common matches between two C# lists, whereby you want to include multiple matching conditions.

To start, here is a typical LINQ statement (and setup) dealing with a single join condition, using the extension method approach (which I prefer), joining two lists; one defining humans and one defining aliens (just because!):

// Setup
public interface ILivingBeing
{
    string Name { get; set; }
    int Age { get; set; }
    void WriteInfo();
}

...

public abstract class LivingBeing : ILivingBeing
{
    public int Age { get; set; }
    public string Name { get; set; }
    public abstract void WriteInfo();
}

...

public class Human : LivingBeing
{
    public override void WriteInfo()
    {
        Console.WriteLine("I am a human who is {0} years old and my name is {1}", Age, Name);
    }
}

...

public class Alien : LivingBeing
{
    public override void WriteInfo()
    {
        Console.WriteLine("I am an alien who is {0} years old and my name is {1}", Age, Name);
    }
}

...

// And finally, the List setup and LINQ itself:
List<Human> humans = new List<Human>
{
    new Human { Name = "Steve", Age = 31 },
    new Human { Name = "Dave", Age = 34 },
    new Human { Name = "Alexa", Age = 56 }
};

List<Alien> aliens = new List<Alien>
{
    new Alien { Name = "Steve", Age = 31 },
    new Alien { Name = "Dave", Age = 76 },
    new Alien { Name = "Poppy", Age = 56 }
};

var matches = humans.Join(aliens, human => human.Name, alien => alien.Name, (human, alien) => human);

Here is an illustration showing the first set of results being used:

LINQ Single Join Condition.

LINQ Single Join Condition.

In the case above the results returned by ‘matches’ include both ‘Steve’ and ‘Dave’ (humans), as a match on the ‘Name’ property can be established across both lists. Everything is fine up until the point we want matches based on, say, the Name and Age properties (on the assumption we want to stick with the extension method approach). This is surprisingly easy to achieve, using anonymous types in our LINQ statement join condition, as follows:

// Return just a list containing the human 'Steve' (as he is the only one who directly matches an alien based on 'Name' and 'Age'
var matches = humans.Join(aliens, human => new { human.Name, human.Age }, alien => new { alien.Name, alien.Age }, (human, alien) => human);

The inner and outer key selectors simply use anonymous types, constructed using the new keyword, to bring the related properties into scope that we wish to match on. Then, hey presto, you can easily handle multiple matching conditions. In this instance, only the human ‘Steve’ is returned, based on a direct match with an alien of the same name/age:

LINQ Multiple Join Condition.

LINQ Multiple Join Condition.

I hope this comes in handy at some point. I’ve been kept fairly busy on the work front recently, hence my blog and twitter feed haven’t exactly been a hive of activity…I’ll work to change that as best I can in the coming weeks and months and carve out more time to publish content.

Cheers, until the next time!

Gordon Ramsay Home-made Fish Fingers with a Chip Butty Application…Just because

There was no need for this post to exist or for these four hundred and thirty-eight (with brackets and other nonsense) random lines of C# code to even see the light of day. For some unknown reason, I woke up over the weekend and spent an hour watching Gordon Ramsay YouTube videos when I came across this amazing looking take on fish fingers with a chip butty:

The video somehow leads me to write the following code. I wasn’t trying to write anything particularly good (i.e. a gaming engine or anything reusable, per say), it’s just an hour or two of me sitting on my tod mindlessly coding to no exacting standards (i.e. it’s all in one file, doesn’t conform to my usual commenting/ordering standards, is horrendously formed and pretty damn awful). Essentially, just enjoy the ‘random factor’ of all of this; you’ll notice I throw in a tonne of exceptions because, in my head, Gordon Ramsay wouldn’t use simple boolean logic to denote if your choice was correct or not, he would throw massive exceptions all over the place (pretty sure this is how he would write his code).

Here it is, very much un-sanitised and untested:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;

namespace GordonRamseyCookingSimulator
{
    class Program
    {
        private static List<string> gordonSoundBites = new List<string>()
        {
            "gordon-clip-one.wav",
            "gordon-clip-two.wav",
            "gordon-clip-three.wav"
        };

        private const string WELL_DONE_SOUND_BITE = "well-done.wav";

        private static SoundPlayer player = new SoundPlayer();

        private const string GOOD_JOB_TEXT = "Good job, moving on...";
        private const string GORDON_DEMANDS_TEXT = "Gordon demands that you choose a {0}";

        private static Dictionary<string, string> complexOptions = new Dictionary<string, string>();

        static void Main(string[] args)
        {
            Console.WindowHeight = 60;
            Console.WindowWidth = 185;
            Console.ForegroundColor = ConsoleColor.Green;
            bool playFailSound = false, continuePlaying = true;

            WriteToConsole($"Let's make Home-made Fish Fingers and a Chip Butty with Gordon Ramsay{ Environment.NewLine }================================================================================");

            do
            {
                try
                {
                    MakeFishFingersWithAChipButty();
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;

                    Console.WriteLine();
                    playFailSound = true;
                    Console.WriteLine("Gordon Ramsay looks upon you with shame. You have failed because: ({0}) - {1}", ex.GetType().Name, ex.Message);
                }

                if (playFailSound)
                {
                    player.SoundLocation = gordonSoundBites[new Random().Next(0, 3)];
                    player.Play();

                    playFailSound = false;
                }

                WriteToConsole("Play again (Y/N followed by enter)");

                continuePlaying = RetrieveTerifiedCooksChoice().Equals("y", StringComparison.InvariantCultureIgnoreCase);

            } while (continuePlaying);
        }

        private static void MakeFishFingersWithAChipButty()
        {
            Console.WriteLine();

            // Cook with the big man
            NavigateThroughThePotatoSelectionForTheButtyTest();
            NavigateThroughThePeelingInstrumentTest();                  // This one should be easy ahem (peeling...peeler!)
            NavigateThroughTheChipPreparationTest();
            NavigateThroughTheChipCookingChoiceTest();
            NavigateThroughTheFishSelectionTest();
            NavigateThroughTheFishPreparationTest();
            NavigateThroughTheHerbSelectionTest();
            NavigateThroughTheCookingInstrumentForFishFingersTest();
            NavigateThroughTheFishFinalCookingStepTest();
            NavigateThroughTheBreadSelectionTest();

            // Freebie from Gordon - He takes pity, and dishes out an awesome nugget of knowledge
            Console.ForegroundColor = ConsoleColor.DarkMagenta;
            WriteToConsole("HEY IDIOT! This one is for free; remember to rub the bread in the chip oil on the tray (do a 'mop' up) and get all of those awesome flavours!");
            Console.ForegroundColor = ConsoleColor.Green;

            // The FINAL TEST!
            NavigateThroughTheFinalServingTest();

            // SUCCESS (woop woop)!!!
            GodJob();

            Console.ForegroundColor = ConsoleColor.DarkMagenta;
            WriteToConsole("You have survived the Home-made Fish Fingers and a Chip Butty challenge! Well done! Press enter to exit...");
            Console.ForegroundColor = ConsoleColor.Green;
        }

        private static void NavigateThroughTheFinalServingTest()
        {
            // Final choice, how does this thing get served?
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "sauce to serve this with and decide if you should share this with others or not:"));
            complexOptions = CreateDictionaryWithOptions("Serve with ketchup and devour everything yourself.",
                "Serve with brown sauce and share (there is enough for two).", "Serve with ketchup and hand the whole dish over to a loved one, you've already eaten.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "A");
        }

        private static void NavigateThroughTheBreadSelectionTest()
        {
            // What type of bread should you use!!!
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "bread type for the chip butty (buttered, of course!):"));
            WriteEnumValuesToConsole<BreadType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<BreadType>(RetrieveTerifiedCooksChoice(), "thickcrustybread");

            // SUCCESS (so far anyway, you're nearly there)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishFinalCookingStepTest()
        {
            // How long should they be cooked and what do you add near the end (when the heat is turned up)?
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "time for how long the fish fingers should be cooked on each side and what secret ingredient should be added near the end of this process:"));
            complexOptions = CreateDictionaryWithOptions("Cook for 3 minutes on each side adding some butter near the end.",
                "Cook for 2 minutes on each side adding some margarine near the end.", "cook for 5 minutes on each side adding some butter near the end.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "A");

            // SUCCESS (so far anyway, getting there)!!!
            GodJob();
        }

        private static void NavigateThroughTheCookingInstrumentForFishFingersTest()
        {
            // What cooking instrument should be used to cook said fish fingers
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "cooking instrument with which to cook your fish:"));
            WriteEnumValuesToConsole<ChefToolsForTheJob>();
            GordonRamsayProcessesYourToolChoiceForFoolishMistakes(RetrieveTerifiedCooksChoice(), ChefToolsForTheJob.Pan);

            // SUCCESS (so far anyway, getting there)!!!
            GodJob();
        }

        private static void NavigateThroughTheHerbSelectionTest()
        {
            // What herb should be used with the fish???
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "herb to chop and use with your breadcrumb mixture for the fish:"));
            WriteEnumValuesToConsole<HerbType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<HerbType>(RetrieveTerifiedCooksChoice(), "dill");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishPreparationTest()
        {
            // Ok, how should the fish be prepared...
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for preparing the fish:"));
            complexOptions = CreateDictionaryWithOptions("Cut into squares, pepper and cover in a little chill powder before coating in seasoned flour, then use egg-wash.",
                "Cut into battons, lightly salt before coating in seasoned flour and rolling, then use egg-wash.", "Cut at an angle, lightly salt and don't flour (just use egg-wash).");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "B");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheFishSelectionTest()
        {
            // Choose the correct fish type
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "fish type for your fish fingers:"));
            WriteEnumValuesToConsole<FishType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<FishType>(RetrieveTerifiedCooksChoice(), "pollock");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheChipCookingChoiceTest()
        {
            // Ok, what do we 'bang' the chips into in order to cook them
            complexOptions.Clear();
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for cooking the chips:"));
            complexOptions = CreateDictionaryWithOptions("Chuck the chips in a roasting hot pan with oil and cook for 10 minutes.",
                "Chuck the chips in the deep fat fryer until done.", "Chuck the chips on an oiled baking tray and cook in a pre-heated oven.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "C");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughTheChipPreparationTest()
        {
            // How do you choose to make the chips???
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "method for making preparing the chips for cooking:"));
            complexOptions = CreateDictionaryWithOptions("Chop, add oil, don't season and add chilli. Then shake.",
                "Chop, blanch, season and add paprika. Then shake.", "Chop, add oil, don't season and add pesto. Then shake.");

            WriteDictionaryValuesToConsole(complexOptions);
            GordonRamsayInspectsYourComplexChoice(RetrieveTerifiedCooksChoice(), "B");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughThePeelingInstrumentTest()
        {
            // Choose the correct peeling method, or you'll become a cropper
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "peeling instrument for your potatoes:"));
            WriteEnumValuesToConsole<ChefToolsForTheJob>();
            GordonRamsayProcessesYourToolChoiceForFoolishMistakes(RetrieveTerifiedCooksChoice(), ChefToolsForTheJob.Peeler);

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static void NavigateThroughThePotatoSelectionForTheButtyTest()
        {
            player.SoundLocation = WELL_DONE_SOUND_BITE;

            // Choose the correct potato type for the chips
            WriteToConsole(string.Format(GORDON_DEMANDS_TEXT, "potato type for your chips:"));
            WriteEnumValuesToConsole<PotatoType>();
            GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<PotatoType>(RetrieveTerifiedCooksChoice(), "desiree");

            // SUCCESS (so far anyway, there is a long way to go)!!!
            GodJob();
        }

        private static Dictionary<string, string> CreateDictionaryWithOptions(params string[] items)
        {
            Dictionary<string, string> complexItems = new Dictionary<string, string>();

            if (items == null || items.Count() == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            List<string> keys = new List<string>() { "A", "B", "C" };

            if (items.Count() > keys.Count())
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            for (int i = 0; i < items.Count(); i++)
            {
                complexItems.Add(keys[i], items[i]);
            }

            return complexItems;
        }

        private static void GodJob()
        {
            player.Play();
            WriteToConsole(Environment.NewLine + GOOD_JOB_TEXT);
        }

        private static void WriteDictionaryValuesToConsole(Dictionary<string, string> complexOptions)
        {
            if (complexOptions == null || complexOptions.Count == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            complexOptions.ToList().ForEach(item =>
            {
                WriteToConsole($"{ item.Value }: type = { item.Key }", false);
            });

            Console.WriteLine();
        }

        private static void GordonRamsayInspectsYourComplexChoice(string choiceString, string gordonsDesiredOutcome)
        {
            if (complexOptions == null || complexOptions.Count == 0)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            if (!choiceString.Trim().Equals(gordonsDesiredOutcome, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new GordonRamsayPoorChefSkillException("GOD DAMN IT, WHY DID YOU DO IT LIKE THAT. USELESS, SIMPLY USELESS - EPIC FAIL!");
            }
        }

        private static void GordonRamsayProcessesYourToolChoiceForFoolishMistakes(string choiceString, ChefToolsForTheJob gordonsDesiredOutcome)
        {
            if ((ChefToolsForTheJob)CheckForAStupidChoiceInGeneral(choiceString) != gordonsDesiredOutcome)
            {
                throw new GordonRamsayPoorChefSkillException("GOD DAMN IT, WHY DID YOU CHOOSE THAT BLOOMING (imagine swearing here) TOOL FOR THE JOB - EPIC FAIL!");
            }
        }

        private static void GordonRamsayProcessesYourIngredientChoiceForFoolishMistakes<T>(string choiceString, string gordonsDesiredOutcome) where T : struct, IConvertible
        {
            if (!typeof(T).IsEnum)
            {
                throw new GordonRamsayEnragedAtTheDeveloperException();
            }

            string choiceFromEnum = Enum.GetName(typeof(T), CheckForAStupidChoiceInGeneral(choiceString));
            if (string.IsNullOrWhiteSpace(choiceFromEnum) || !choiceFromEnum.Equals(gordonsDesiredOutcome, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new GordonRamsayWrongIngredientException("WRONG, WRONG, WRONG INGREDIENT!!! - EPIC FAIL");
            }
        }

        private static int CheckForAStupidChoiceInGeneral(string choiceString)
        {
            int choiceValue;
            if (!int.TryParse(choiceString, out choiceValue))
            {
                throw new GordonRamsayInvalidChoiceException("YOU DIDN'T GIVE ME A BLOOMING (imagine swearing here) NUMBER - EPIC FAIL!");
            }

            return choiceValue;
        }

        private static string RetrieveTerifiedCooksChoice()
        {
            Console.ForegroundColor = ConsoleColor.Blue;

            Console.Write("MAKE YOUR CHOICE: ");
            string choice = Console.ReadLine();
    
            Console.ForegroundColor = ConsoleColor.Green;

            return choice;
        }

        private static void WriteToConsole(string text, bool addAdditionalNewLine = true)
        {
            Console.WriteLine(text + (addAdditionalNewLine ? Environment.NewLine : string.Empty));
        }

        private static void WriteEnumValuesToConsole<T>() where T : struct, IConvertible 
        {
            Type typePassedIn = typeof(T);

            if (typePassedIn.IsEnum)
            {
                Enum.GetValues(typePassedIn).Cast<T>().ToList().ForEach(item =>
                {
                    Enum enumValue = Enum.Parse(typeof(T), item.ToString()) as Enum;
                    WriteToConsole($"{ item }: type = { Convert.ToUInt32(enumValue) }", false);
                });
            }

            Console.WriteLine();
        }
    }

    public enum BreadType
    {
        MediumSlicedGranary = 0,
        HovisHalfAndHalf = 1,
        Baguette = 2,
        ThickCrustyBread = 3
    }

    public enum HerbType
    {
        Basil = 0,
        Chives = 1,
        Dill = 3,
        Sage = 4,
        Tarragon = 5
    }

    public enum FishType
    {
        Haddock = 0,
        Pollock = 1,
        Tuna = 2,
        Salmon = 3
    }

    public enum PotatoType
    {
        Desiree = 0,
        KingEdward = 1,
        Laura = 2,
        MelodyPotato = 3
    }

    public enum ChefToolsForTheJob
    {
        RustySpoon = 0,
        Peeler = 1,
        Screwdriver = 2,
        Pan = 3,
        Griddle = 4
    }

    public class GordonRamsayInvalidChoiceException : Exception
    {
        public GordonRamsayInvalidChoiceException(string message)
            : base(message)
        {

        }
    }

    public class GordonRamsayWrongIngredientException : Exception
    {
        public GordonRamsayWrongIngredientException(string message)
            : base(message)
        {

        }
    }
    
    public class GordonRamsayPoorChefSkillException : Exception
    {
        public GordonRamsayPoorChefSkillException(string message)
            : base(message)
        {

        }
    }

    public class GordonRamsayEnragedAtTheDeveloperException : Exception
    {
        public GordonRamsayEnragedAtTheDeveloperException()
            : base("OMG, YOU ARE SO INCOMPETENT. THIS SOFTWARE DEVELOPER DOESN'T KNOW HOW HIS OWN CODE SHOULD WORK. SHOCKING!")
        {

        }
    }
}

It takes the form of a beautiful console application; here it is in full swing:

Gordon Ramsay Cooking Challenge.

Gordon Ramsay Cooking Challenge.

For extra kicks, I forced my wife to play it to…adding annoying sound bites (for success and failure, in each case, to cover all of my bases):

Claire Epic Failing.

Claire Epic Failing.

Claire Nailing It.

Claire Nailing It.

It felt pretty darn good to just rattle out a piece of random, not that well thought out code. I think I just needed to write ‘something’, so this is what we have ended up with for better or for worse. I urge you to write something awful (just for yourself, not for your day job, unless you quite like the idea of being tossed out onto the street that is!) and get liberated, just for once! There is quite a bit of pressure sometimes to conform to standards, practice patterns, etc. This is all good and well, but just remember that you can always just hammer out something ill-thought for yourself and enjoy doing so; sometimes it can be just the ticket! 😉

I seem to be, as it was pointed out to me today, late to the Gordon Ramsay game-based party anyway:

Gordon Ramsay Dash

There will be more golden, crispy, fish finger like coding posts coming soon; in the meantime have a great morning/afternoon (or evening/night) depending on when you read this, bye for now!

Be a Dependency Injection Ninja with Ninject

Howdy all,

Firstly, a big old fashioned apology for not being ‘on-the-wire’ much over recent weeks. It’s been an interesting time having accepted an exciting new job, which is amazing; but I’ve also had to contend with a few other sizeable life-boulders off to the side. Nothing I can’t handle, of course, so here I am back with you :-).

I find myself about a third of the way through what I can only express to you as an excellent book (so far); ASP.NET Web API 2: Building a REST Service from Start to Finish. It seems prudent to go over a couple of notable sections that have caught my eye so far. The first topic of conversation is using Ninject for Dependency Injection, which I’ve found to be a solid and compelling alternative to Autofac; the latter I’ve already covered in this post. I’ll follow this up, in a one-two punch style, with a small ASP.NET Web API project showcasing a very cool Namespace HTTP Controller Selector, introduced as a very useful utility class in the book. Best intentions, of course, to produce and roll out these posts as close to one another as possible, so I’ll do my best!

Moving on swiftly, in order to quickly run through the pertinent pieces of the Ninject puzzle, I’ve crafted a very trivial console application that represents a ‘Robot Factory’, painting and outfitting (with weapons) robots that, once deployed, move, speak and attempt to murder one another (being a console application some imagination will be required, ahem!).

Now you know the ‘what’, let’s take a look at the ‘how’ (plus look at Ninjects involvement here as a Dependency Injection solution). We’re basically plugging in the concept of an IoC (Inversion of Control) Container here.

Program Structure

Let’s, to get this ball a-rollin’, have a look at a class diagram outlining our application:

Overview of the Robot Factory Application by Class Diagram.

Robot Factory Application Class Diagram.

Being a console application, the inception point will be the traditional Main method within the Program class:

Program Class

using Ninject;
using Ninject.Modules;
using RobotArmyProcessingLine.DI;
using RobotArmyProcessingLine.Interface;
using System;
using System.Linq;

namespace RobotArmyProcessingLine
{
    /// <summary>
    /// Core RobotArmyProcessingLine Application.
    /// </summary>
    class Program
    {
        #region Private Static IKernel Ninject Container

        /// <summary>
        /// Represents the IKernel Ninject Container
        /// for this RobotArmyProcessingLine Application.
        /// </summary>
        private static IKernel container;

        #endregion Private Static IKernel Ninject Container

        #region Main Application Entry Point

        /// <summary>
        /// RobotArmyProcessingLine Main entry point.
        /// </summary>
        /// <param name="args">Optional input arguments for this application.</param>
        static void Main(string[] args)
        {
            // Configure the Ninject DI Container ready for use (before the application kicks in
            ConfigureNinjectForApplication();

            // Run the application 'proper'
            RunApplication();
        }

        #endregion Main Application Entry Point

        #region Ninject Static Configuration Method

        /// <summary>
        /// Private static helper method that configures the Ninject
        /// Container for use in this test application.
        /// </summary>
        private static void ConfigureNinjectForApplication()
        {
            // Create a StandardKernel object, adding in INinjectModule supporting 
            // objects (all with a load method binding interfaces to concrete types)
            container = new StandardKernel(new INinjectModule[]
            {
                new FactoryModule(),
                new FactoryUtilityModule(),
                new RobotModule()
            });
        }

        #endregion Ninject Static Configuration Methods

        #region Private Static Application Methods

        /// <summary>
        /// Private static helper method that creates a 
        /// 'Factory' and kicks off the process of deploying robots.
        /// </summary>
        private static void RunApplication()
        {
            IRobotFactory robotFactory;

            try
            {
                // Attempt to retrieve a Robot Factory (based in a mapping to the IRobotFactory interface)
                robotFactory = container.TryGet<IRobotFactory>();

                if (robotFactory != null)
                {
                    // We retrieved a valid 'Factory'. Add Robots to the Factory and 'Process' 
                    // and 'Deploy' them if the Factory is not 'oversubscribed' and is therefore functional
                    robotFactory.AddRobots(GetTestRobots());

                    if (robotFactory.FactoryOperational)
                    {
                        PerformFactoryProcessing(robotFactory);
                        DeployRobots(robotFactory);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred whilst processing/deploying Robots: Exception Message: " + ex.Message);
            }

            Console.ReadLine();
        }

        /// <summary>
        /// Private static helper test method that generates
        /// a basic list of test Robots.
        /// </summary>
        /// <returns>A List of IRobot supporting objects.</returns>
        private static IRobot[] GetTestRobots()
        {
            return new IRobot[]
            {
                (IRobot)container.TryGet<ISmallRobot>(),
                (IRobot)container.TryGet<ISmallRobot>(),
                (IRobot)container.TryGet<ISmallRobot>(),
                (IRobot)container.TryGet<ISmallRobot>(),
                (IRobot)container.TryGet<ILargeRobot>(),
                (IRobot)container.TryGet<ILargeRobot>(),
                (IRobot)container.TryGet<ILargeRobot>(),
                (IRobot)container.TryGet<ILargeRobot>()
            };
        }

        /// <summary>
        /// Private static helper that triggers a Robot Factories
        /// Paint/AttachWeapons methods (affecting Robots in the Factory).
        /// </summary>
        /// <param name="robotFactory">The Robot Factory to trigger actions on.</param>
        private static void PerformFactoryProcessing(IRobotFactory robotFactory)
        {
            if (robotFactory != null)
            {
                robotFactory.PaintRobots();
                robotFactory.AttachWeapons();
            }
        }

        /// <summary>
        /// Private static helper that triggers a Robot Factories
        /// DeployRobots method (affecting Robots in the Factory).
        /// </summary>
        /// <param name="robotFactory">The Robot Factory to trigger the action on.</param>
        private static void DeployRobots(IRobotFactory robotFactory)
        {
            // If Factory is not null then deploy the Robots
            robotFactory?.DeployRobots().ToList().ForEach(robot =>
            {
                // If each robot is not null then trigger various robot behaviours (move, speak, attack, etc.) and 'output', depending on implementation
                if (robot != null)
                {
                    robot.Move();
                    robot.Speak();
                    robot.Attack();

                    if (robot is ISmallRobot)
                    {
                        ((ISmallRobot)robot).Sneak();
                    }
                    else if (robot is ILargeRobot)
                    {
                        ((ILargeRobot)robot).Crush();
                    }
                }

                Console.WriteLine();
            });
        }

        #endregion Private Static Application Methods
    }
}

To get started, the project in question needs to bring into scope the appropriate Ninject assembly, which can be done via Nuget (either the Package Manager or Package Manager Console):

Ninject Nuget Package via the Nuget Package Manager.

Ninject Nuget Package.

As far as the code goes, there are a few things to discuss here. Much like with Autofac, the concept of a Dependency Injection container is key and takes the form of an IKernel supporting object (we’re using a private, static reference here for demonstration purposes). The container is ‘configured’ within the ConfigureNinjectForApplication method using a set of module based classes. In short, these modules are used, keeping logical grouping at the very fore of the thought process here, to bind interfaces to concrete types; that’s basically it. We’ll see these modules fully fleshed out later, but notice how we can pass an array of modules to the StandardKernel constructor, which causes every single module’s Load method to be called, binding ‘services’ to ‘implementations’.

After the very high-level Ninject configuration step the RunApplication method is triggered, which gets the configured implementation (based on module setup) of IRobotFactory using the TryGet method on the container, which returns null if a ‘mapped’ type cannot be found (a Ninject container supports a Get method also, but I’ve opted for a TryGet here, meaning no exception is raised in this scenario if a mapping cannot be found between the interface specified and a concrete type).

Once we have the robot factory we add some test robots to it with the aid of the GetTestRobots method, using the container to get an array of IRobot supporting types. The list technically contains small and large robots, which implement different interfaces actually; more on this later.

Factories can paint and arm robots, and this functionality on the factory is triggered by the PerformFactoryProcessing method. The way in which robots are painted and armed is cleverly handled by Dependency Injection, based on mappings between the IPainter/IWeaponAttacher interfaces and concrete types (again by custom classes inheriting from NinjectModule).

Finally, robots are deployed for combat and move, speak, attack and perform interface specific actions, just for kicks more than anything! The way in which robots ‘output’ their various actions is also tied to a little sprinkling of DI; I’ll discuss this as we move forward.

Ninject Dependency Injection Module Configuration

As you saw earlier a little bit of magic occurs within the Program class and the ConfigureNinjectForApplication method. A StandardKernel type is created here, passing in an array of INinjectModule supporting types. These modules, as mentioned before, just contain logical groupings of mappings between interfaces and concrete types. When a container is asked to ‘resolve’ (in Autofac speak) or ‘get’ instances based on an interface, the mapped concrete type is returned; simples! Time for a wee squiz at our custom modules, which all inherit from the NinjectModule type:

using Ninject.Modules;
using RobotArmyProcessingLine.Interface;
using RobotArmyProcessingLine.Production;

namespace RobotArmyProcessingLine.DI
{
    /// <summary>
    /// Denotes a Ninject Factory Module 
    /// determining the mappings between Robot 
    /// Factory Interfaces and associated Concrete Types.
    /// </summary>
    public class FactoryModule : NinjectModule
    {
        #region Overridden Load Method

        /// <summary>
        /// Overridden Load method to bind services
        /// to concrete types.
        /// </summary>
        public override void Load()
        {
            // Bind IRobotFactory to a concrete type (in this case, as a singleton - i.e. same instance return when the container
            // is asked to 'get' an instance based on the interface)
            Bind<IRobotFactory>().To<LargeRobotFactory>().InSingletonScope();
        }

        #endregion Overridden Load Method
    }
}

.....

using Ninject.Modules;
using RobotArmyProcessingLine.Interface;
using RobotArmyProcessingLine.Model;

namespace RobotArmyProcessingLine.DI
{
    /// <summary>
    /// Denotes a Ninject Factory Utility Module 
    /// determining the mappings between Robot 
    /// Factory Utility Interfaces and associated Concrete Types. 
    /// </summary>
    public class FactoryUtilityModule : NinjectModule
    {
        #region Overridden Load Method

        /// <summary>
        /// Overridden Load method to bind services
        /// to concrete types.
        /// </summary>
        public override void Load()
        {
            // A 'Factory' is able to paint robots and attach weapons. Map services (interfaces) to concrete
            // types for when a 'get' on the Ninject IoC container is used
            Bind<IPainter>().To<BlueWaterPaintMachine>().InSingletonScope();
            Bind<IWeaponAttacher>().To<RocketLauncherAttacher>().InSingletonScope();
        }

        #endregion Overridden Load Method
    }
}

.....

using Ninject.Modules;
using RobotArmyProcessingLine.Interface;
using RobotArmyProcessingLine.Model;

namespace RobotArmyProcessingLine.DI
{
    /// <summary>
    /// Denotes a Ninject Robot Module 
    /// determining the mappings between Robot 
    /// Interfaces and associated Concrete Types. 
    /// </summary>
    public class RobotModule : NinjectModule
    {
        #region Overridden Load Method

        /// <summary>
        /// Overridden Load method to bind services
        /// to concrete types.
        /// </summary>
        public override void Load()
        {
            // Determine the concrete types associated with ISmallRobot and ILargeRobot
            Bind<ISmallRobot>().To<SmallRobotV1>();
            Bind<ILargeRobot>().To<LargeRobotV1>();

            // Something a bit different here. We bind slightly different concrete types to IRobotOutputter based on
            // the type it is being 'injected' into (determines how robots output information about commands they undertake)
            Bind<IRobotOutputter>().To<RobotOutput>().WhenInjectedInto<ISmallRobot>().InSingletonScope();
            Bind<IRobotOutputter>().To<RobotFileOutput>().WhenInjectedInto<ILargeRobot>().InSingletonScope();
        }

        #endregion Overridden Load Method
    }
}

These custom module class types are hopefully pretty terse. All modules override the base class Load method and are where the logic is housed to bind interfaces to implementations, nothing more and nothing less. I’ve split the mappings for the factory and the factory constructor arguments into two separate modules, just for a clean separation, although I have to admit I would need to do some further reading up to reveal the truth behind best practice here.

Ninject employs a ‘fluent’ declarative style, using chained method calls to determine the various facets of how an interface is mapped to a concrete type, for example (or control the specifics on how a concrete instance is returned). By default, types are returned in a ‘transient’ nature; meaning you get a new instance of a type each and every time a get operation is performed using the container. However, you can probably spot that I have used the InSingletonScope method that will force a single instance of a type to be created and returned constantly when requested from the container.

The RobotModule type has a little extra trickery going in in relation to how requests for IRobotOutputter implementing objects are handled when requested from the container. Ninject enables you to return a different concrete implementation, when an interface type is requested, depending on the type it is being injected into (i.e. via constructor injection, for example). Here, a request for an IRobotOutputter implementing type will result in either a RobotOutput or RobotFileOutput type, depending on whether it is being passed into a small or large robot, respectively. This is so very, very cool!

To summarize, create the custom modules you require (deriving from NinjectModule and overriding the Load method) and bind interfaces to concrete types, always keeping in mind if you need singletons or new instances when requests are made from the container. Then, consider if you need further control over how types are bound and returned, depending on the interplay between types (i.e. what are they being injected into for example). You should then be in pretty good shape.

I have found the Ninject help documentation to be fairly good in pointing out the nuances of how this works and options available to you; I’ll include a link at the end of this blog post for further perusal (you can actually handle service/implementation hooking up via an XML mapping file, if you choose, so read up!) ;-).

We’ve seen what the core program class does and how our Ninject DI container is configured using modules/interface and type mappings. Now, strut your way on to seeing the interfaces and types relating to factories and robots.

The Robot Factory

Factories!!! The core backbone of our robot making world! They paint, arm and deploy our robots.

I’ve done my best here to adhere to the ‘D’ of the SOLID design principles; Dependency Inversion (which is a different concept to Dependency Injection, and should not be confused). In order to paint and attach weapons to robots, factories rely on the IPainter and IWeaponAttacher abstractions only, and no actual concrete types (decoupling this class so that it does not have fixed dependency on a specific concrete type). Ninject, on the flip-side, handles the Dependency Injection process for us and passes in appropriate types for us when a factory is created, based on module mappings discussed earlier on.

There is an IRobotFactory interface for starters, defining common factory behaviours as follows:

using System.Collections.Generic;

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Core interface describing shared behaviours
    /// for a 'Factory' in this application.
    /// </summary>
    public interface IRobotFactory
    {
        #region Interface Properties

        /// <summary>
        /// Interface property that can be implemented
        /// to control the specifics behind 
        /// whether a 'Factory’ is operational or not.
        /// </summary>
        bool FactoryOperational { get; }

        #endregion Interface Properties

        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented to kick
        /// off a Factories ability to Paint Robots.
        /// See <seealso cref="IPainter"/> and 
        /// <seealso cref="IRobot"/> for linked behaviour objects.
        /// </summary>
        void PaintRobots();

        /// <summary>
        /// Interface method that can be implemented to kick
        /// off a Factories ability to arm Robots.
        /// See <seealso cref="IWeaponAttacher"/> and 
        /// <seealso cref="IRobot"/> for linked behaviour objects.
        /// </summary>
        void AttachWeapons();

        /// <summary>
        /// Interface method that can be implemented to control
        /// how <see cref="IRobot"/> based objects are added
        /// to a particular Factories production line.
        /// </summary>
        /// <param name="robotsToAdd">An array (params or set array) of <see cref="IRobot"/> implementing objects to add to the Factory production line.</param>
        void AddRobots(params IRobot[] robotsToAdd);

        /// <summary>
        /// Interface method that can be implemented to control
        /// how <see cref="IRobot"/> objects, within a factory, are
        /// deployed back to the front lines (aka, the method caller).
        /// </summary>
        /// <returns>An <see cref="IList{T}"/> of <see cref="IRobot"/> based objects.</returns>
        IList<IRobot> DeployRobots();

        #endregion Interface Methods
    }
}

Fairly basic stuff; factories paint, arm and deploy robots. Robots can be added to a factories production line using the AddRobots method (only the abstraction of IRobot is used here). All factories have a mechanism for returning a boolean stating if the factory is operational (which I didn’t fully tie into the final implementations, so definite scope for improvement here).

A RobotFactory abstract base class models what a basic factory looks like, using IRobotFactory:

using RobotArmyProcessingLine.Interface;
using System.Collections.Generic;
using System.Linq;

namespace RobotArmyProcessingLine.Production
{
    /// <summary>
    /// Base class defining shared elements for all robot factories.
    /// Provides abstract members and <see cref="IRobotFactory"/> based members.
    /// </summary>
    public abstract class RobotFactory : IRobotFactory
    {
        #region Private Fields

        /// <summary>
        /// An <see cref="IPainter"/> based object for painting robots in the factory.
        /// </summary>
        private IPainter paintMachine;

        /// <summary>
        /// An <see cref="IWeaponAttacher"/> based object for arming robots in the factory.
        /// </summary>
        private IWeaponAttacher weaponAttacherMachine;

        #endregion Private Fields

        #region Protected (Get) Properties

        /// <summary>
        /// Allow a factory access to the robots (<see 
        /// cref="IRobot"/> types) in the production line.
        /// </summary>
        protected List<IRobot> Robots { get; private set; }

        #endregion Protected (Get) Properties

        #region Public Abstract Properties

        /// <summary>
        /// public abstract member that needs to be implemented by
        /// deriving factories to determine the conditions under which
        /// the factory is operational (i.e. the production line is not overloaded).
        /// </summary>
        public abstract bool FactoryOperational { get; }

        #endregion Public Abstract Properties

        #region Constructor

        /// <summary>
        /// Constructor for a RobotFactory that sets
        /// the <see cref="IPainter"/> and <see cref="IWeaponAttacher"/> implementing
        /// objects on this type (all factories can paint/arm robots).
        /// </summary>
        /// <param name="paintMachineToUse">An <see cref="IPainter"/> implementing object for this factory to paint robots.</param>
        /// <param name="weaponAttacherMachineToUse">An <see cref="IWeaponAttacher"/> implementing object for this factory to arm robots.</param>
        public RobotFactory(IPainter paintMachineToUse, IWeaponAttacher weaponAttacherMachineToUse)
        {
            Robots = new List<IRobot>();
            paintMachine = paintMachineToUse;
            weaponAttacherMachine = weaponAttacherMachineToUse;
        }

        #endregion Constructor

        #region IRobotFactory Interface Methods

        /// <summary>
        /// public method that paints robots on the production line.
        /// </summary>
        public void PaintRobots()
        {
            Robots?.ForEach(robot =>
            {
                paintMachine.Paint(robot);
            });
        }

        /// <summary>
        /// public method that attaches weapons to robots on the production line. 
        /// </summary>
        public void AttachWeapons()
        {
            Robots?.ForEach(robot =>
            {
                weaponAttacherMachine.AttachWeapons(robot);
            });
        }

        /// <summary>
        /// public method that adds robots (<see cref="IRobot"/> objects) on to the production line. 
        /// </summary>
        /// <param name="robotsToAdd">An array of type <see cref="IRobot"/> defining the robots to add to the production line.</param>
        public void AddRobots(params IRobot[] robotsToAdd)
        {
            if (robotsToAdd?.Count() > 0)
            {
                Robots.AddRange(robotsToAdd);
            }
        }

        /// <summary>
        /// public method that deploys robots off the production line.
        /// Clears down the production line in the factory and returns all robots to the caller.
        /// </summary>
        /// <returns>Returns an <see cref="IList{T}"/> of <see cref="IRobot"/> types.</returns>
        public IList<IRobot> DeployRobots()
        {
            // Copy robots to a new IList - Ready for deployment
            IList<IRobot> robotsToDeploy = new List<IRobot>(Robots);

            // Clear the current production line
            Robots.Clear();

            // Deploy!
            return robotsToDeploy;
        }

        #endregion IRobotFactory Interface Methods
    }
}

You’ll see the small and large factories in a second, which really just allow me to determine different conditions for a factory being ‘operational’. As for the abstract base class outlined here; when trying to properly decouple types from each other and keep interactions between types based purely on abstractions, a common approach you will come across is pushing all dependencies ‘up’ to the constructor. The constructor can then be geared to accept interface types and references can then simply be stored for use within the class (see the private IPainter and IWeaponAttacher fields). We are freed from the need to ‘new-up’ instances of types within the body of methods in this class, which would instantly introduce coupling and unrequired dependencies. The methods for painting, arming and adding robots are fairly self-explanatory (notice the standard use of containment-delegation mechanics here to just ‘delegate’ on calls for painting/arming robots to the IPainter and IWeaponAttacher objects, without this type needing to use/know about concrete implementations), I’ll leave you to mull over these. When robots are deployed, they leave the ‘production line’ queue and are returned to the caller for use in the ‘field’; there is a fantastic robot war going on in my mind anyway!

For completeness, here are the implementations for the small and large robot factories, both deriving from the RobotFactory type (we use constructor chaining here to pass the IPainter and IWeaponAttacher types up to the base class, and override the FactoryOperational property; that being about it!):

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Production
{
    /// <summary>
    /// Type that defines a 'large' factory that can process
    /// (paint, arm and deploy) <see cref="IRobot"/> implementing objects.
    /// Utilises <seealso cref="IPainter"/> and <seealso cref="IWeaponAttacher"/> utility classes.
    /// </summary>
    public class LargeRobotFactory : RobotFactory
    {
        #region Public Overridden Properties

        /// <summary>
        /// public overridden property that determines if this
        /// factory is operational. This factory is not operational
        /// if the production line (robot count) exceeds the maximum limit
        /// (we could of course add additional logic in here for this factory type).
        /// </summary>
        public override bool FactoryOperational
        {
            get
            {
                return Robots?.Count <= 20;
            }
        }

        #endregion Public Overridden Properties

        #region Constructor

        /// <summary>
        /// Constructor for a LargeRobotFactory that passes
        /// the <see cref="IPainter"/> and <see cref="IWeaponAttacher"/> implementing
        /// object to the base class (all factories can paint/arm robots).
        /// </summary>
        /// <param name="paintMachineToUse">An <see cref="IPainter"/> implementing object for this factory to paint robots.</param>
        /// <param name="weaponAttacherMachineToUse">An <see cref="IWeaponAttacher"/> implementing object for this factory to arm robots.</param>
        public LargeRobotFactory(IPainter paintMachineToUse, IWeaponAttacher weaponAttacherMachineToUse)
            : base(paintMachineToUse, weaponAttacherMachineToUse)
        {

        }

        #endregion Constructor
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Production
{
    /// <summary>
    /// Type that defines a 'small' factory that can process
    /// (paint, arm and deploy) <see cref="IRobot"/> implementing objects.
    /// Utilises <seealso cref="IPainter"/> and <seealso cref="IWeaponAttacher"/> utility classes.
    /// </summary>
    public class SmallRobotFactory : RobotFactory
    {
        #region Public Overridden Properties

        /// <summary>
        /// public overridden property that determines if this
        /// factory is operational. This factory is not operational
        /// if the production line (robot count) exceeds the maximum limit
        /// (we could of course add additional logic in here for this factory type).
        /// </summary>
        public override bool FactoryOperational
        {
            get
            {
                return Robots?.Count <= 10;
            }
        }

        #endregion Public Overridden Properties

        #region Constructor

        /// <summary>
        /// Constructor for a SmallRobotFactory that passes
        /// the <see cref="IPainter"/> and <see cref="IWeaponAttacher"/> implementing
        /// object to the base class (all factories can paint/arm robots).
        /// </summary>
        /// <param name="paintMachineToUse">An <see cref="IPainter"/> implementing object for this factory to paint robots.</param>
        /// <param name="weaponAttacherMachineToUse">An <see cref="IWeaponAttacher"/> implementing object for this factory to arm robots.</param>
        public SmallRobotFactory(IPainter paintMachineToUse, IWeaponAttacher weaponAttacherMachineToUse)
            : base(paintMachineToUse, weaponAttacherMachineToUse)
        {

        }

        #endregion Constructor
    }
}

If you’re interested, here are the IPainter and IWeaponAttacher interface definitions, along with concrete implementations (that you’ll see being mapped within the FactoryUtilityModule Ninject configuration class):

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Interface describing behaviours
    /// for a Painting Machine that can operate 
    /// against an <see cref="IRobot"/> implementing object.
    /// </summary>
    public interface IPainter
    {
        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented
        /// to 'Paint' an <see cref="IRobot"/> implementing object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> implementing type to paint.</param>
        void Paint(IRobot robot);

        #endregion Interface Methods
    }
}

.....

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Interface describing behaviours
    /// for a Weapon Attachment Machine that can operate 
    /// against an <see cref="IRobot"/> implementing object.
    /// </summary>
    public interface IWeaponAttacher
    {
        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented
        /// to 'attach weapons' to an <see cref="IRobot"/> implementing object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> implementing type to attach weapons to.</param>
        void AttachWeapons(IRobot robot);

        #endregion Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Defines a type that can be used to paint <see cref="IRobot"/>
    /// objects with blue, water-based paint.
    /// </summary>
    public class BlueWaterPaintMachine : IPainter
    {
        #region Private Constants

        /// <summary>
        /// Private constant that holds a description of how this paint
        /// machine will paint a given robot.
        /// </summary>
        private const string paintDescription = "painted in blue, water-based paint";

        #endregion Private Constants

        #region Public IPainter Interface Methods

        /// <summary>
        /// Public method that paints the passed in 
        /// <see cref="IRobot"/> object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> to be painted (if it's not null).</param>
        public void Paint(IRobot robot)
        {
            // If the robot is not null then paint it
            robot?.Paint(paintDescription);
        }

        #endregion Public IPainter Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Defines a type that can be used to paint <see cref="IRobot"/>
    /// objects with red, lead-based paint.
    /// </summary>
    public class RedLeadPaintMachine : IPainter
    {
        #region Private Constant

        /// <summary>
        /// Private constant that holds a description of how this paint
        /// machine will paint a given robot.
        /// </summary>
        private const string paintDescription = "painted in red, lead-based paint";

        #endregion Private Constant

        /// <summary>
        /// Public method that paints the passed in 
        /// <see cref="IRobot"/> object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> to be painted (if it's not null).</param>
        public void Paint(IRobot robot)
        {
            // If the robot is not null then paint it
            robot?.Paint(paintDescription);
        }
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Defines a type that can be used to arm <see cref="IRobot"/>
    /// objects with a minigun.
    /// </summary>
    public class MinigunAttacher : IWeaponAttacher
    {
        #region Private Constants

        /// <summary>
        /// Private constant that holds a description of how this weapon
        /// attachment machine will arm a given robot.
        /// </summary>
        private const string weaponDescription = "minigun attachment!";

        #endregion Private Constants

        #region Public IWeaponAttacher Interface Methods

        /// <summary>
        /// Public method that arms the passed in 
        /// <see cref="IRobot"/> object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> to be armed (if it's not null).</param>
        public void AttachWeapons(IRobot robot)
        {
            robot?.AttachWeapons(weaponDescription);
        }

        #endregion Public IWeaponAttacher Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Defines a type that can be used to arm <see cref="IRobot"/>
    /// objects with a rocket launcher.
    /// </summary>
    public class RocketLauncherAttacher : IWeaponAttacher
    {
        #region Private Constants

        /// <summary>
        /// Private constant that holds a description of how this weapon
        /// attachment machine will arm a given robot.
        /// </summary>
        private const string weaponDescription = "rocket launcher attachment!";

        #endregion Private Constants

        #region Public IWeaponAttacher Interface Methods

        /// <summary>
        /// Public method that arms the passed in 
        /// <see cref="IRobot"/> object.
        /// </summary>
        /// <param name="robot">The <see cref="IRobot"/> to be armed (if it's not null).</param>
        public void AttachWeapons(IRobot robot)
        {
            robot?.AttachWeapons(weaponDescription);
        }

        #endregion Public IWeaponAttacher Interface Methods
    }
}

That’s the factories all set and ready to rock and roll! So, what about the robots you ask? On to that next :-).

The Robots

Much like the factories, robots utilise an IRobot interface that a base class implements to give us a feel for standard behaviours that all robots share:

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Core interface describing shared behaviours
    /// for a 'Robot' in this application.
    /// </summary>
    public interface IRobot
    {
        #region Interface Properties

        /// <summary>
        /// Interface property that describes
        /// a robots paint job.
        /// </summary>
        string PaintDescription { get; }

        /// <summary>
        /// Interface property that describes
        /// a robots weapon attachment.
        /// </summary>
        string WeaponDescription { get; }

        #endregion Interface Properties

        #region Interface Methods

        /// <summary>
        /// Interface method that, when 
        /// implemented, 'moves' a robot.
        /// </summary>
        void Move();

        /// <summary>
        /// Interface method that, when 
        /// implemented, makes a robot 'speak'.
        /// </summary>
        void Speak();

        /// <summary>
        /// Interface method that, when 
        /// implemented, makes a robot 'speak'.
        /// </summary>
        void Attack();

        /// <summary>
        /// Interface method that, when implemented, controls
        /// the specifics of how a robot is painted. This ties 
        /// to an<seealso cref="IPainter"/> implementing 
        /// object (of an <seealso cref="IRobotFactory" /> object).
        /// </summary>
        /// <param name="robotPaintDescription">A string that provides details on the robot paint job.</param>
        void Paint(string robotPaintDescription);

        /// <summary>
        /// Interface method that, when implemented, controls
        /// the specifics of how a robot receives weapon attachments.
        /// This ties to an <seealso cref="IWeaponAttacher"/> 
        /// implementing object (of an <seealso cref="IRobotFactory" /> object).
        /// </summary>
        /// <param name="robotWeaponAttachmentDescription">A string that provides details on the robots weapon attachments.</param>
        void AttachWeapons(string robotWeaponAttachmentDescription);

        #endregion Interface Methods
    }
}

As we’ve mentioned a few times now (hopefully I haven’t sent you to sleep by stating the same bloody stuff over and over again!) robots can move, speak and attack. They also have properties that denote how they have been painted and armed, along with methods that allow the paint and armament descriptions to be set for each robot. Again, a pretty egg-suck style interface this one.

Time for the Robot abstract base class then:

using System;
using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Provides an abstract, base definition for all robots
    /// in this application, utlising the <see cref="IRobot"/> interface.
    /// </summary>
    public abstract class Robot : IRobot
    {
        #region Protected (Get) Properties

        /// <summary>
        /// The <see cref="IRobotOutputter"/> implementing object that can
        /// be used to determine how this robot outputs messages.
        /// </summary>
        protected IRobotOutputter MessageOutputter { get; private set; }

        #endregion Protected Properties

        #region Public (Get) Properties

        /// <summary>
        /// The description of the paint job applied to this robot
        /// after it has been through the factory production line (or some other process).
        /// </summary>
        public string PaintDescription { get; private set; }

        /// <summary>
        /// The description of the weapon attachments applied to this robot
        /// after it has been through the factory production line (or some other process).
        /// </summary>
        public string WeaponDescription { get; private set; }

        #endregion Public (Get) Properties

        #region Constructor

        /// <summary>
        /// Constructor for this base class that consumes and sets
        /// this types <see cref="IRobotOutputter"/> object for
        /// handling how a robot pushes out messages.
        /// </summary>
        /// <param name="outputter">The <see cref="IRobotOutputter"/> object for the robot to use for messaging.</param>
        public Robot(IRobotOutputter outputter)
        {
            // Robots must be able to output, no exceptions (i.e. throw an exception! Probably bad comment wording ahem)
            if (outputter == null)
            {
                throw new ArgumentNullException(nameof(outputter));
            }

            MessageOutputter = outputter;
        }

        #endregion Constructor

        #region Public Abstract IRobot Interface Methods

        /// <summary>
        /// Public abstract method that must be overridden by
        /// deriving types to determine how a robot attacks.
        /// </summary>
        public abstract void Attack();

        /// <summary>
        /// Public abstract method that must be overridden by
        /// deriving types to determine how a robot moves.
        /// </summary>
        public abstract void Move();

        /// <summary>
        /// Public abstract method that must be overridden by
        /// deriving types to determine how a robot speaks.
        /// </summary>
        public abstract void Speak();

        #endregion public abstract IRobot Interface Methods

        #region Public IRobot Interface Methods

        /// <summary>
        /// Public method that is used to pass details
        /// of a paint job to this robot.
        /// </summary>
        /// <param name="robotPaintDescription">The paint job applied to the robot.</param>
        public void Paint(string robotPaintDescription)
        {
            PaintDescription = robotPaintDescription;
        }

        /// <summary>
        /// Public method that that is used to pass details
        /// of the weapon that is to be used by this robot.
        /// </summary>
        /// <param name="robotWeaponAttachmentDescription">The weapon added to the robot.</param>
        public void AttachWeapons(string robotWeaponAttachmentDescription)
        {
            WeaponDescription = robotWeaponAttachmentDescription;
        }

        #endregion Public IRobot Interface Methods
    }
}

Bit by bit then…

We’ve implemented the Paint and AttachWeapons methods at this level, which just sets the paint job and armament description for this robot, easy peasy. The Attack, Move and Speak methods are fully abstract here and I’ll be forcing derived class types to implement these (small/large robots are going to perform these actions differently). Again, dependencies have been ‘pushed’ to the constructor. All robots ‘output’ their actions using an IRobotOutputter implementing type; this is me going abstraction crazy for demonstration purposes, and sticking to the Dependency Inversion principle as closely as I can of course!

Robot derived implementations will be using this IRobotOutputter type, as you can see here (small and large robots are ‘versioned’, although that doesn’t really play a massive part in this iteration of the application; if you are following along you could swap out V1 for V2 variants in the appropriate Ninject module mapping class just to prove a point):

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Provides the definition for a Version 1, 'Small Robot'.
    /// </summary>
    public sealed class SmallRobotV1 : Robot, ISmallRobot
    {
        #region Constructor

        /// <summary>
        /// Constructor for a SmallRobotV1, which passes
        /// a <see cref="IRobotOutputter"/> object to the 
        /// <seealso cref="Robot"/> base class for future use.
        /// </summary>
        /// <param name="outputter">The <see cref="IRobotOutputter"/> object to determine how this robot outputs command details.</param>
        public SmallRobotV1(IRobotOutputter outputter)
            : base(outputter)
        {

        }

        #endregion Constructor

        #region IRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot attack.
        /// </summary>
        public override void Attack()
        {
            MessageOutputter.WriteLine($"SmallRobotV1 { PaintDescription ?? string.Empty } attacking with a { WeaponDescription ?? string.Empty }!");
        }

        /// <summary>
        /// Public method that makes this robot move.
        /// </summary>
        public override void Move()
        {
            MessageOutputter.WriteLine($"SmallRobotV1 { PaintDescription ?? string.Empty } moving!");
        }

        /// <summary>
        /// Public method that makes this robot speak.
        /// </summary>
        public override void Speak()
        {
            MessageOutputter.WriteLine($"SmallRobotV1 { PaintDescription ?? string.Empty } speaking!");
        }

        #endregion IRobot Interface Methods

        #region ISmallRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot sneak.
        /// </summary>
        public void Sneak()
        {
            MessageOutputter.WriteLine($"SmallRobotV1 { PaintDescription ?? string.Empty } sneaking!");
        }

        #endregion ISmallRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Provides the definition for a Version 2, 'Small Robot'.
    /// </summary>
    public sealed class SmallRobotV2 : Robot, ISmallRobot
    {
        #region Constructor

        /// <summary>
        /// Constructor for a SmallRobotV2, which passes
        /// a <see cref="IRobotOutputter"/> object to the 
        /// <seealso cref="Robot"/> base class for future use.
        /// </summary>
        /// <param name="outputter">The <see cref="IRobotOutputter"/> object to determine how this robot outputs command details.</param>
        public SmallRobotV2(IRobotOutputter outputter)
            : base(outputter)
        {

        }

        #endregion Constructor

        #region IRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot attack.
        /// </summary>
        public override void Attack()
        {
            MessageOutputter.WriteLine($"SmallRobotV2 { PaintDescription ?? string.Empty } attacking with a { WeaponDescription ?? string.Empty }!");
        }

        /// <summary>
        /// Public method that makes this robot move.
        /// </summary>
        public override void Move()
        {
            MessageOutputter.WriteLine($"SmallRobotV2 { PaintDescription ?? string.Empty } moving!");
        }

        /// <summary>
        /// Public method that makes this robot speak.
        /// </summary>
        public override void Speak()
        {
            MessageOutputter.WriteLine($"SmallRobotV2 { PaintDescription ?? string.Empty } speaking!");
        }

        #endregion IRobot Interface Methods

        #region ISmallRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot sneak.
        /// </summary>
        public void Sneak()
        {
            MessageOutputter.WriteLine($"SmallRobotV2 { PaintDescription ?? string.Empty } sneaking!");
        }

        #endregion ISmallRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Provides the definition for a Version 1, 'Large Robot'.
    /// </summary>
    public sealed class LargeRobotV1 : Robot, ILargeRobot
    {
        #region Constructor

        /// <summary>
        /// Constructor for a LargeRobotV1, which passes
        /// a <see cref="IRobotOutputter"/> object to the 
        /// <seealso cref="Robot"/> base class for future use.
        /// </summary>
        /// <param name="outputter">The <see cref="IRobotOutputter"/> object to determine how this robot outputs command details.</param>
        public LargeRobotV1(IRobotOutputter outputter)
            : base(outputter)
        {

        }

        #endregion Constructor

        #region IRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot attack.
        /// </summary>
        public override void Attack()
        {
            MessageOutputter.WriteLine($"LargeRobotV1 { PaintDescription ?? string.Empty } attacking with a { WeaponDescription ?? string.Empty }!");
        }

        /// <summary>
        /// Public method that makes this robot move.
        /// </summary>
        public override void Move()
        {
            MessageOutputter.WriteLine($"LargeRobotV1 { PaintDescription ?? string.Empty } moving!");
        }

        /// <summary>
        /// Public method that makes this robot speak.
        /// </summary>
        public override void Speak()
        {
            MessageOutputter.WriteLine($"LargeRobotV1 { PaintDescription ?? string.Empty } speaking!");
        }

        #endregion IRobot Interface Methods

        #region ILargeRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot crush.
        /// </summary>
        public void Crush()
        {
            MessageOutputter.WriteLine($"LargeRobotV1 { PaintDescription ?? string.Empty } crushing!");
        }

        #endregion ILargeRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Provides the definition for a Version 2, 'Large Robot'.
    /// </summary>
    public sealed class LargeRobotV2 : Robot, ILargeRobot
    {
        #region Constructor

        /// <summary>
        /// Constructor for a LargeRobotV2, which passes
        /// a <see cref="IRobotOutputter"/> object to the 
        /// <seealso cref="Robot"/> base class for future use.
        /// </summary>
        /// <param name="outputter">The <see cref="IRobotOutputter"/> object to determine how this robot outputs command details.</param>
        public LargeRobotV2(IRobotOutputter outputter)
            : base(outputter)
        {

        }

        #endregion Constructor

        #region IRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot attack.
        /// </summary>
        public override void Attack()
        {
            MessageOutputter.WriteLine($"LargeRobotV2 { PaintDescription ?? string.Empty } attacking with a { WeaponDescription ?? string.Empty }!");
        }

        /// <summary>
        /// Public method that makes this robot move.
        /// </summary>
        public override void Move()
        {
            MessageOutputter.WriteLine($"LargeRobotV2 { PaintDescription ?? string.Empty } moving!");
        }

        /// <summary>
        /// Public method that makes this robot speak.
        /// </summary>
        public override void Speak()
        {
            MessageOutputter.WriteLine($"LargeRobotV2 { PaintDescription ?? string.Empty } speaking!");
        }

        #endregion IRobot Interface Methods

        #region ILargeRobot Interface Methods

        /// <summary>
        /// Public method that makes this robot crush.
        /// </summary>
        public void Crush()
        {
            MessageOutputter.WriteLine($"LargeRobotV2 { PaintDescription ?? string.Empty } crushing!");
        }

        #endregion ILargeRobot Interface Methods
    }
}

.....

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Interface describing additional behaviours
    /// for a 'Large' Robot.
    /// </summary>
    public interface ILargeRobot
    {
        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented
        /// to perform a 'crush' action.
        /// </summary>
        void Crush();

        #endregion Interface Methods
    }
}

.....

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Interface describing additional behaviours
    /// for a 'Small' Robot.
    /// </summary>
    public interface ISmallRobot
    {
        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented
        /// to perform a 'sneak' action.
        /// </summary>
        void Sneak();

        #endregion Interface Methods
    }
}

It’s kinda noddy right! Hopefully, it proves the point and is enough to demonstrate the mechanics at work later down the line, when the application is run. All robots use the base class MessageOutputter property (which will be a singleton instance of an IRobotOutputter supporting type, based on the RobotModule configuration class we saw earlier) to push out information to a particular output channel. The constructor, much like the factory, is just pushing a dependency up to the base class. Notice the use of the ISmallRobot and ILargeRobot interface types; these are used to denote slight differences in behaviour between robots. Small robots can sneak and large robots crush.

Lastly, before we see the application running, I want to focus on how robots handle their output. Robots again use an abstraction, the IRobotOutputter interface, to handle this. This means the specifics of how output is performed is not tied into the Robot class at all:

namespace RobotArmyProcessingLine.Interface
{
    /// <summary>
    /// Interface describing behaviours
    /// for a Robot Output Module (so that a Robot
    /// can provide details via a designated IO channel
    /// on its various actions (e.g. movement, attacking, etc.).
    /// This is currently utilised by <seealso cref="IRobot"/> implementing objects.
    /// </summary>
    public interface IRobotOutputter
    {
        #region Interface Methods

        /// <summary>
        /// Interface method that can be implemented to control
        /// how (i.e. to what IO Channel, for example) an object publishes messages.
        /// </summary>
        /// <param name="outputMessage"></param>
        void WriteLine(string outputMessage);

        #endregion Interface Methods
    }
}

The implementations control how the WriteLine method actually works. In this sample application, I’ve gone with one type that writes output to the console and another that pushes information to a file, as follows:

using RobotArmyProcessingLine.Interface;
using System;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Type that is used to define an IO (console-based) output
    /// method as a robot messaging output.
    /// </summary>
    public class RobotOutput : IRobotOutputter
    {
        #region IRobotOutputter Interface Methods

        /// <summary>
        /// Allows a message to be output to the console.
        /// See <see cref="IRobot"/> implementing classes for usage.
        /// </summary>
        /// <param name="outputMessage">The message to process.</param>
        public void WriteLine(string outputMessage)
        {
            Console.WriteLine(outputMessage);
        }

        #endregion IRobotOutputter Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;
using System;
using System.IO;

namespace RobotArmyProcessingLine.Model
{
    /// <summary>
    /// Type that is used to define an IO (file-based) output
    /// method as a robot messaging output.
    /// </summary>
    public class RobotFileOutput : IRobotOutputter
    {
        #region IRobotOutputter Interface Methods

        /// <summary>
        /// Allows a message to be output to a file.
        /// See <see cref="IRobot"/> implementing classes for usage.
        /// </summary>
        /// <param name="outputMessage">The message to process.</param>
        public void WriteLine(string outputMessage)
        {
            File.AppendAllText("Robot-output.txt", outputMessage + Environment.NewLine);
        }

        #endregion IRobotOutputter Interface Methods
    }
}

This again is incredibly cool, for the pure fact that the reliance on System.IO is not forced upon robot type implementations and is fully tucked away and packaged based upon an interface, loosely-coupled dependency. Robots ‘output’, but have no reliance on knowing how that output is performed, very nice!

Right back near the beginning of this post you’ll remember that the IRobotOutputter interface was mapped, during Ninject module configuration, to these two concrete types depending upon whether it was being injected into ISmallRobot or ILargeRobot supporting types. We’ll see that in action below, so hang on in there.

Running the Program

Here are the results, based on our Ninject container configuration and module setup, in motion.

First up, a breakpoint set within the LargeRobotFactory constructor shows that when the TryGet method of the StandardKernel container is called this type is ‘injected’ (based on module configuration) with a BlueWaterPaintMachine and a RocketLauncherAttacher. See the FactoryUtilityModule for reference:

Large Robot Factory Constructor debugging showing concrete types in use at run-time.

Large Robot Factory Constructor Debugging.

Next, robot-based type DI kicks in when test robots are created to be placed on a factories production line. Small and Large robots are injected with, as per the RobotModule Ninject configuration module, RobotOutput and RobotFileOutput types respectively. I’ve called the GetHashCode method in the Immediate Window to illustrate, on two different constructor calls for each robot type, that the same instance of an IRobotOutputter supporting type has been supplied (see the WhenInjectedInto method usage in the RobotModule class for full details again):

Small Robot Constructor debugging showing concrete types being passed in.

Small Robot Constructor Debugging.

Large Robot Constructor debugging showing concrete types being passed in.

Large Robot Constructor Debugging.

We’ve reached (well, nearly) the end of this rather large post…and we have output! The factory has gone to work and painted/armed our robots. Once deployed, they have had their move, speak, attack, sneak and crush functionality triggered. Output of each robot has been determined via DI configuration; small robots have written output to the console and large robots have, as expected, placed output in a file:

Robot factory application output in full.

Robot Factory Application Output.

That hopefully gives you a good primer for configuring Ninject and binding interfaces to implementations (illustrating some of the more common features), ultimately to use DI for your projects.

If you want to have a bit more of a read up then check out the documentation here:

Ninject Documentation

Thanks for reading, this (looking back over it now) has been a bit of a beast of a post again; a massive pat on the back if you’ve read the lot, always appreciated.

All the best and until the next time!

C# Interactive Initialisation Trick

Hi there,

A little aside this one; something very, very cool that I’ve noticed with the advent of Visual Studio Update 2. Without question, this rates as a MUST CHECK OUT Visual Studio feature.

The first complaint (and a valid one, no question about it) in regards to the C# Interactive Window was that running your own code was a little bit of a painstaking process, requiring you to load dlls and supporting references manually, using the #r command. Now, with update 2, initialising C# Interactive with your applications context is a cinch.

For starters, right-click on the project you are interested in and select the Initialize Interactive with Project option, within the Solution Explorer:

Showing how to Initialise Interactive with Project.

Initialise Interactive with Project Option.

This, as you’ll see, does all of the ‘scaffolding’ work for you within the C# Interactive Window, and injects a using statement for the default namespace to get you started. You should see something like the following:

C# Interactive Window initialised so that the Project is in scope.

C# Interactive Window Initialised with Project.

From here on in, you are free to start adding using statements, as required, and begin writing code against the types in the target project; in a completely pain-free fashion. A massive thumbs up…you can now go wild, like this for example:

Example of using Project Code from C# Interactive.

Using Project Code from C# Interactive.

I did try this on a larger, more complex and tightly-coupled code base and I can comfortably say you’ll have issues depending on how things are structured. Smaller, more loosely-coupled types, where SOLID principals have been adhered to are going to allow you to use C# Interactive in this way with more ease.

It is also possible to highlight portions of code, in any file, and right-click the Execute in Interactive option to run with, and execute, smaller chunks of functionality.

Posts on the way to cover some elements of the ASP.NET Web API and Ninject Dependency Injection (hopefully, at some point over the weekend), so watch this space.

Have a good weekend all and I’ll be back with you in a jiffy…

Coding Snippets in Sublime Text 3

Hello,

This is my coup de grâce into coding snippets, which completes this mini-series (for now, at least). I wanted to do a tiny bit more Python, so began investigating which IDE to look into next:

Stackoverflow – Which Python IDE
Best Python IDE

The Eric IDE project caught my eye initially, and definitely looks like an incredibly interesting prospect. However, I find myself inexorably drawn to try out Sublime Text 3, only because I seem to have crossed paths with a fair few people using it. If anyone is interested in checking out the Eric IDE I’ve included a set of links below for further investigation:

Prerequisites

Eric IDE Prerequisites Listed
Python
PyQt

Downloads

Eric IDE Sourceforge Download

For now, let’s focus our efforts on Sublime Text 3…

Sublime Text 3

To get started, you can navigate to the Sublime Text 3 downloads page and grab the appropriate package for your OS. After reading up, there appears to be a project accessible on GitHub called Anaconda which ‘turns Sublime Text 3 into a full featured Python development IDE’. In order to utilise this functionality, you’ll first need (well, this is the easiest way from the options listed) Package Control, which is essentially a Package Manager for Sublime.

Here are a few basic notes for getting Anaconda setup with Sublime Text 3:

Image showing setup notes on installing Anaconda for Sublime Text 3.

Notes on setting up Anaconda.

In addition, this blog post looks like a strong starting point for investigation into setting up Sublime Text 3 for Python development:

Sublime Text as Python IDE

Just to prove the point, here is Anaconda showing its presence via a context menu in the IDE:

Image showing Anaconda in use within Sublime Text 3.

Anaconda in use.

I’ve taken a few additional steps here. For starters, I wanted to run my code directly within Sublime, which requires configuring the correct Build System, as follows:

Image showing how to setup the Python Build System in Sublime Text 3.

Setting Python Build System.

After performing the Build System configuration you can decide on whether you want to use syntax-only style checks or physically run your code on build (‘Tools > Build With‘):

Image showing the Sublime Build With options.

Sublime Build With.

So, as far as setup goes, that covers it. On to snippets…

Snippets in Sublime

To the main event, how do you create snippets in Sublime Text 3?

Creating the snippet itself couldn’t be simpler, just navigate to ‘Tools > Developer > New Snippet…’ and you’ll be presented with the following:

Image showing the default setup for a snippet in Sublime Text 3.

Snippet Default Setup.

The idea behind creating a snippet is conceptually similar to how you would create them for use within Visual Studio. With the content element (again, we are dealing with an XML format) you’ll find a CDATA definition; snippet code goes between the square brackets. Placeholders can be defined within the code snippet using the $ symbol followed by an incremental number, starting at one (depending on how many placeholders you have of course). The tabTrigger element defines the shortcut that needs to be typed into the IDE code window to bring the snippet into scope. Additional metadata can also be provided to specify the scope of a certain code snippet (e.g. just Python) and a friendly, textual description (stored in the aptly named description element). It sticks pretty close to other snippet creation conventions I’ve seen elsewhere, it’s certainly a cinch to pick up. Here is my first stab at a completed snippet, with comments left in line for reference:

<snippet>
	<content><![CDATA[
def saySomething(name):
	print("$1", name)
]]></content>
	<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
	<tabTrigger>ss</tabTrigger>
	<!-- Optional: Set a scope to limit where the snippet will trigger -->
	<scope>source.python</scope>
    <description>Say Something Snippet</description>
</snippet>

Snippet files are saved using the .sublime-snippet extension and for the purposes of a quick demonstration I’ve saved mine in the default location of ‘C drive > Users > MY_USER > AppData > Roaming > Sublime Text 3 > Packages > User’, this would require a bit more thought if you were creating more snippets (if you have organisational OCD such as I do). Initial reading does suggest that they should be saved under the ‘User’ directory regardless.

Within Sublime you will then need to save a file with a .py extension, ready to actually construct some Python code! The next two images show the newly created ‘say-something.sublime-snippet’ being brought into scope by keying in ‘ss’ and then hitting tab. As before, placeholders can be tabbed through for fast snippet completion:

Image showing the snippet before use.

Snippet before use.

Image showing the snippet after use.

Snippet after use.

Placeholder values, within snippets, can accept defaults by using the following convention:

<snippet>
	<content><![CDATA[
def saySomething(name):
	print("${1:Hello}", name)
	print (${2:5} + ${3:5})
]]></content>
	<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
	<tabTrigger>ss</tabTrigger>
	<!-- Optional: Set a scope to limit where the snippet will trigger -->
	<scope>source.python</scope>
    <description>Say Something Snippet</description>
</snippet>

That’s it, mini-series completed! As mentioned before I have a gargantuan mound of topics to cover, some just bubbling over in my mind and others sitting as draft posts ready for completion, so there is plenty of content on its way. Until the next time, have a great weekend!

Coding Snippets (Live Templates) in IntelliJ IDEA (OMG Java!)

Good evening folks!

This is somewhat of an experimental post. I’ve written this purely ‘in the heat of battle’, whilst I was trying to illustrate how to do this. A little bit of a departure from my usual posts; whereby I research a subject and then give you a condensed and refined product. Why did I do this? Just an interesting experiment in all honesty. On the subject of the word honest, this style of post is a chance to be authentic and more in the moment, even if I do trip up here and there and expose myself as the occasional fool; it’s a chance to see my internal monologue as I go about trying to learn something on the fly. I hope you enjoy…

I have an amazing, now completely out of control and rather feral, list of topics in my ‘to blog about’ list. Finding myself in the mood to be a ‘completionist’ however, I really should make something of this coding snippets mini-series and pack a few more of these in before I call it quits.

Today I’m looking at IntelliJ IDEA, a JetBrains IDE for coding in Java (and more than just that, if the tag line is anything to go by). This IDE has been selected out of the magic hat just because I wanted to go for something that I haven’t heard too much about before, rather than a name more frequently bandied about, such as the NetBeans IDE. This received a solid mention in Robert C. Martins ‘The Clean Coder’, which I’ve just finished digesting, so it seems most worthy of an intellectual punt!

Getting your hands on IntelliJ IDEA

To get mitts on this IDE is simple enough. I started by going here:

Choose your Edition

There you’ll find links to a Community and Ultimate edition (with Ultimate having a free, thirty-day trial). As I’m not doing a review per se on this software I won’t dig into the particulars of each edition too heavily. For anyone wondering what the different offerings entail you can navigate to the Compare Edition page and have a gander. What I will say is that language support beyond Java is most certainly a thing (.Net languages are out, as you may expect) and if you’re using Git you appear to be golden in relation to the Community edition; only Ultimate supports TFS.

Let’s get this install done and figure out a) how to write some Java and b) encapsulate something into a snippet.

Installing IntelliJ IDEA

Installing the product is, as you would expect, a next…next…next affair. I opted for the desktop shortcut (I have a messy desktop) and rigged it so that anything with a .java file extension would be associated with this IDE. On running the application you get prompted to import previous, custom settings. I’ve got none so an easy choice for me. After reading those pesky ‘policies’ (that we all read in minute detail of course!) you get, which is a nice touch, an opportunity to pick a theme (for those who know me, its dark themes all the way) and customise/install plugins. Again, I’m not really doing a review but I really liked the ease of the setup process here; being accustomed to Visual Studio for the main part I can often see times when (despite all of the functionality it does offer, I’m not bashing on it) it’s heavyweight nature does show through, not always for the best.

So, we’re ready to rock and roll; being presented with the following screen:

IntelliJ Start Screen.

IntelliJ Start Screen.

Making that Magic Coding Snippet!

Ok, so far, so good. I’m hoping that (although I’ve gazed at a fair bit of Java through my time) not having written a single line of Java is not going to be a ‘blocker’ to success ;-). The remit of this blog post is just to show how to create a code snippet, no matter how simple that is. Besides, I have read and digested the following books, so I’m feeling ready:

Googling the Error Message.

Googling the Error Message.

Copying and Pasting from Stack Overflow.

Copying and Pasting from Stack Overflow.

Create New Project seems like the way to go! I proceeded using the following tutorials by the way, should you wish to follow along:

IntelliJ IDEA Documentation

My first issue appeared to be the fact that I didn’t have the Software Development Kit installed (JDK in this instance), so I navigated here to grab one, for 64 bit Windows in my case:

JDK Downloads

Time for a cup of tea at this point; find a suitable beverage for yourself as you continue to read through, you’ve earned it by hanging on this long :-). On a side note, whoever bought me this mug needs to take a trip to the opticians. I do wonder if I could rock a twirled moustache too:

Someone needs an Optician.

Someone needs an Optician.

I downloaded and installed this package without any bother. Going back to create a new project again, I was able to (yes, I Stack Overflowed my way to glory here – I rather idiotically selected the ‘jre’ folder) hit New and navigate to the root JDK folder under my default Java install directory, as follows:

JDK Directory Selection in the IntelliJ IDEA.

JDK Directory Selection in the IntelliJ IDEA.

This brings me to a promising point on hitting next…I can make a command line application which, right now for me, is grade-a territory; that will do nicely thank you very much (I know where I stand with a Main() method after all):

Create a Command Line Application in IntelliJ.

Create a Command Line Application in IntelliJ.

After being nosey on Java rules of Package Naming, and naming my actual project, I was presented with this amazing sight:

IntelliJ Simple Command Line Application.

IntelliJ Simple Command Line Application.

As you can probably see the project name is ‘FizzBuzz’ related, so I’m going to write code to solve this classic problem and get a code snippet in along the way.

Ten minutes later I have this, which apart from questionable string handling, does the job I’m after (just needed to figure out how to print content to the output window and convert integers to string; refrained from googling here and just went on an IntelliSense rampage, which equals an ‘apologies if this is incorrect’). The output, without any unit tests to back it up, gives me expected ‘Fizz’ for multiples of three, ‘Buzz’ for multiples of five, ‘FizzBuzz’ for multiples of three and five, or just the number for everything else.

package lg.snippet.testing;

public class Main {

    public static void main(String[] args) {
        fizzBuzzerTest();
    }

    private static void fizzBuzzerTest() {
        for (int j = 1; j <= 100; j++) {
            System.out.println(evaluateInput(j));
        }
    }

    private static String evaluateInput(int fizzBuzzInput) {
        String fizzBuzzString = "";

        if (fizzBuzzInput % 3 == 0) {
            fizzBuzzString = "Fizz";
        }

        if (fizzBuzzInput % 5 == 0) {
            fizzBuzzString += "Buzz";
        }

        if (fizzBuzzString == "") {
            fizzBuzzString = Integer.toString(fizzBuzzInput);
        }

        return fizzBuzzString;
    }
}
FizzBuzz Command Line Output.

FizzBuzz Command Line Output.

That’s the best piece of Java I will fashion today, happy for it to be ripped to shreds by all the experts out there.

So, although this has been somewhat of a ramble, we are now ready to fashion a code snippet. I’m going to make the snippet encapsulate the fizzBuzzerTest method and supporting evaluateInput method, as a complete package that can be dropped anywhere. The way this is achieved, after a little research, is via Live Templates.

To get started, navigate to File > Settings and select the Live Templates section under Editor. In this next screenshot, I’m creating a new custom Template Group to act as a repository for my own weird and wonderful snippets:

Live Template Options.

Live Template Options.

After creating the custom template group you can repeat the process (with the new group highlighted) to add a new Live Template. The template itself has a few configuration options that need to have valid settings before you can proceed. Firstly, define what ‘contexts’ this Live Template can operate within; for the purposes of this little example only Java is applicable:

Defining the Live Template Context.

Defining the Live Template Context.

I gave my Live Template an abbreviation (allowing easy accessing from the editor), a Description (the one you’ll see in this screen shot I amend before saving, as it was blooming terrible!) as well as the actual code that defines the template. I’ve placed the variable COUNT into my template, which allows the template user to switch out the value when the template is brought into scope (with a default value as shown here; the dialog for managing this being accessible via the Edit Variables button). Variables must be wrapped in ‘$’ symbols and default literals must be wrapped in double quotes in order for this to work (another google-fest here!):

Completing the Live Template Definition.

Completing the Live Template Definition.

Remit basically complete…we’ve done snippets (well, Live Templates) in Java via IntelliJ IDEA! The next two screen shots show the template in use, achieved by hitting tab to generate the snippet after typing the abbreviation. We are also illustrating the place holder for the COUNT variable being editable. The variables can be tabbed through, as you would expect, for fast template completion:

Before Live Template Usage.

Before Live Template Usage.

After Live Template Usage.

After Live Template Usage.

There’s our random walkabout of IntelliJ IDEA and Live Templates done and dusted, mission complete. Cheers all, until the next time happy coding!