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!!!

OpenCover UI – Unit Test Code Coverage

A little sideline post to tide everyone over (as I’m still working on the Alexa piece, which I want to do proper justice to when it’s released). I’ve been messing around with a few rough and ready projects and wanted to get an idea of how to dig into code coverage, in respect of Unit Tests.

I’m currently using Visual Studio 2015 Community Edition and from what I gather no built-in support exists for non-enterprise editions, at the moment. The first hit I found was for the OpenCover UI extension; so I thought I’d take it for a spin to see what it’s made of:

Stack Overflow OpenCover UI Mention

Just so that you can get a feel for where I am at, here is an image outlining a home-brew project that shows some Unit Tests in play:

Unit Test Structure.

Unit Test Structure.

Nothing too miraculous here, I’m just using the standard Unit Testing framework and a little Moq for kicks. To follow this up, I then grabbed hold of the OpenCover UI (.vsix extension) from here and installed it:

OpenCover UI VS Marketplace Link

Let’s roll on from here with some ‘off the cuff’ observations, rather than in-depth review of features, etc. This serves as simply my first impressions and, ultimately, an insight into if we can get the coverage metrics I am after quickly and easily. For starters, you’ll notice a new context menu for ‘OpenCover’ when Visual Studio boots up:

OpenCover Menu.

OpenCover Menu.

I have quickly shoved the inbuilt Test Explorer window next to the OpenCover variant; they appear to offer a similar ‘look and feel’, in addition to functional grouping options (the default Test Explorer windows appears to have a few more options, in fact). The OpenCover Test Explorer oddly doesn’t have a ‘Run’ or ‘Run All’ tests buttons, on the face of it anyway (or debugging options). Right clicking a test gives a ‘Cover with OpenCover’ context menu option…guess I’ll see what that does now!

Cover with OpenCover Context Menu Option.

Cover with OpenCover Context Menu Option.

At this point I hit the following, immediate, explosion:

Open Cover EXE Error.

OpenCover EXE Error.

You then get prompted to hunt down the relevant .exe file. As I was fishing around for this I decided to go back to the trusty Stack Overflow, to see what wisdom could be uncovered. This was the first hit, which outlined that a configuration file, with set content, needed to be stuffed in with the solution content:

Further Stack Overflow Wisdom

Further comment sniffing did highlight, under Tools > Options, that additional configuration should be performed (i.e. the .exe path should be specified):

Open Cover VS Options.

Open Cover VS Options.

I decided that hunting on NuGet might be the best way to expose an .exe file here (i.e. getting something dropped into a packages directory, which I can easily pick up). So, I followed the hunch by adding this package (just to the ‘tests’ project, for starters, as I wasn’t sure which projects needed targeting):

OpenCover Nuget Package.

OpenCover Nuget Package.

I don’t feel as if we’ve fallen into a rabbit hole just yet, but at this point, I’ve started to wonder if ‘storms’ are on the horizon! Hopefully, we won’t have to tread too much further to get this machine churning. Installing the NuGet package had the desired effect, I have now got the .exe I was looking for lingering in a ‘Tools’ directory, under the OpenCover folder within packages, which I’ve setup in the Visual Studio Options section:

OpenCover EXE Path Configured.

OpenCover EXE Path Configured.

This shouldn’t be marked down as ‘ideal’ configuration, of course; we’re more leaning towards a ‘just get it working’ stance.

The moment of truth…..right clicking and selecting ‘Cover with OpenCover’ now….success! Well, good things appear to have happened anyway, let’s have a quick review to see if we can make sense of it (code with incomplete XML comments is about to be on show, so apologies about that!). I only ran the one test by the way:

Unit Test Code Coverage.

Unit Test Code Coverage.

First observation; it did seem to take a good few seconds before all of the lines covered (green dots) and not covered (red dots) seemed to be highlighted correctly, nothing too catastrophic in this, however. As far as the unit testing specific code goes, here you can clearly see which tests I ran in this instance, the UI pointers are very self-explanatory. One additional observation, it looks like it could be a touch tricky to pick out breakpoints amongst the code coverage markers, but I don’t see this as a big issue at the moment (I’ll have to see how I feel after extended use). In fact, the OpenCover Results window has an option for enabling/disabling these markers, so we’re all good.

You’ll notice that the unit test method denoted here is placing the ‘AddItemCleansingMappingElementToConfiguration’ method under test, so I am keen to see what lines we hit (or ‘covered’) within the targeted method:

Code Actually Under Test Covered.

Code Actually Under Test Covered.

The idea here is that the XML configuration passed to this method is, in fact, malformed so the statement where the ‘addSuccessful’ variable is set to true is not hit (an exception is triggered, and caught, by the preceding line of code); which mirrors the indicator provided by OpenCover, nice! I call this a success!

I’m now going to run this across the board and see what floats to the surface.

Ah, look at this! For starters, OpenCover has highlighted a problem with one of my unit tests in a very solid, visual way (I was wondering why no lines of this test were covered, until I realised I omitted the ‘Test Method’ attribute!):

Missing Test Method Attribute.

Missing Test Method Attribute.

A couple of quirks that deserve to be noted; firstly, I did have to run the ‘Cover with OpenCover’ command twice to register coverage on all tests (some seemed to be omitted from the process, but then included on the second run through). Also, tests that are geared to expect exceptions to be thrown are always marked with their closing brace as ‘not covered’ (I’m assuming that an exception being thrown legitimately causes the final line to never be hit, therefore not covered, which in my head is expected behaviour – it would be good if there was a way to disregard these instances):

Unit Test Missing Coverage.

Unit Test Missing Coverage.

So what about the actual code ‘under test’ and the metrics provided to show how much of it has been covered? In instances whereby code had been highlighted as not covered (spot checks only, of course), I have to say it appears accurate and has been useful in flagging areas I should really have tested.

As for the actual report metrics, it is exactly what I was after when I started on my way down this road. You get to see the percentage of code coverage at project, class and member level (along with ‘Sequence Points’ visited against the total count of possible points):

OpenCover Metrics Report.

OpenCover Metrics Report.

Sequence points don’t tie directly to ‘lines’, as outlined here. You’ll notice that this is a link detailing a ‘Report Generator‚Äô, which uses XML extracted using OpenCover directly. To finish up, I’ll follow the steps outlined on Stack Overflow again (got to love it, especially if you need information on the double!):

Using the Report Generator

The Report Generator can be downloaded by using NuGet again:

OpenCover Report Generator on NuGet.

OpenCover Report Generator on NuGet.

The Report Generator source code itself can be downloaded from this link.

It looks like you can create a custom report via C#, by implementing an interface, etc. For now, I’m going to do a simple run through using the command line interface. This is the command (after a bit of trial and error) that got me the XML report, for starters:

"C:\Source\Utility Applications\DesktopManager\packages\OpenCover.4.6.519\tools\OpenCover.Console.exe" -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\mstest.exe" -targetargs:"/noisolation /testcontainer:\"C:\Source\Utility Applications\DesktopManager\DesktopManager.Tests\bin\Debug\DesktopManager.Tests.dll\" /resultsfile:C:\Reports\MSTest\.trx" -mergebyhash -output:C:\Reports\MSTest\projectCoverageReport.xml

This was just a case of specifying locations for the OpenCover.console.exe, the mstest.exe and the location of the ‘Tests’ dll for my specific application. XML file in hand, I trigerred this command to generate the final report resources:

"C:\Source\Utility Applications\DesktopManager\packages\ReportGenerator.2.5.2\tools\ReportGenerator.exe" -reports:"C:\Reports\MSTest\projectCoverageReport.xml" -targetdir:"C:\Reports\CodeCoverage"

In a few quick steps you’ll have a set of HTML ‘reports’, as you can see here:

HTML Reports Generated.

HTML Reports Generated.

Let’s finish up with a couple of examples illustrating the outputs:

Index Report.

Index Report.

Configuration Helper Report Details.

Configuration Helper Report Details.

Configuration Helper Report Details.

Configuration Helper Report Line Coverage.

I think that brings us to a close. This seems like pretty powerful stuff; but, I think I’ll need more time to go through some of the outputs and try this with a larger project. I hope this has been fun and/or useful.

Thanks all!

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!

SEO – Gouging Eyes out with Rusty Spoons

A very short piece on my current, off-the-wall, opinions on my little SEO journey so far and the shenanigans we’ve faced up to this point.

Ok, so it hasn’t been¬†that bad! Plus it’s interesting I have opted to use ‘spoons’, and not just a singular spoon. It looks like I plan to¬†gouge¬†out both my eyes at once based on the post title!

I have certainly had moments of scratching my head as to what the hell is going on and SEO often brings up questions like ‘is¬†option¬†a, b, c, z or a combination of some or all, the best way to approach it?’; which quickly leads to the questioning of every blooming decision you plan to make to the nth degree!

With the website ‚Äėfundamentally‚Äô finished (ok, I‚Äôm completely and utterly lying, I want to rewrite massive chunks in the usual ‚Äėunhappy with the code as soon as you‚Äôve finished writing it‚Äô, developer condition, or sickness if you will!), we have desperately been trying to hike our way up the rankings. This has, after a painstaking process, happened; to some degree at least.

I picked this book up for starters, as all good things start with a good read; don’t be put off by the whopping great name:

SEO 2016: Learn search engine optimization with smart internet marketing strategies

After reading this and (thanks for this by the way) picking a few brains of SEO boffins and asking friends to pick additional boffin brains for me, I was ready to start making some of the larger, more critical changes.

So, in no particular order, here were the ideas and concepts that I feel have made the most impact in the short time we have been climbing the SEO mountain…

Page Titles and Page Descriptions

This, without a shadow of a doubt, had the largest impact. We, quite literally, just added unique metadata to each page and ensured our titles and descriptions were informative, without skipping out on the correct keyword combinations we were targeting.

Up until this point the web applications that I have produced, out in the wild, have been linked to from other sites (i.e. local authorities, for example); these other sites took on the burden of SEO and it most cases were sought out for the services they provide (i.e. it was non-commercial in a sense and the traffic was not being fought over).

Now I find myself competing for these precious nuggets of traffic, this takes the biggest bite of the biscuit for me. We went from completely impossible to find, for a small subset of keywords we were targeting, to being on page 3 of the search results (a little variance across Google and Bing, but just a rough approximation). Not perfect, but a very good start!

Keyword Optimisation

This took a couple of days to do in the end. This boiled down to, in essence, looking for keyword combinations with good levels of traffic but lower degrees of difficulty when it came to competition. We ended up spreading our eggs amongst a few baskets here and did target a few competitive keywords; only in an effort to make our content as natural and accurate as possible (clarity/quality of content is also a ranking factor, after all).

We used the Moz tools for this job; this was to check out keyword densities of comparable sites and then plan some alternatives. These references can be found here (you get a month’s free trial by the way):

Moz Keyword Explorer

Moz Open Site Explorer

This has had some impact, once our site was re-crawled and re-indexed. Just from a content quality perspective, it was well worth running everything through Grammarly. I have the Chrome Plugin but, in this instance, I used a Word Plugin to get the job done (you can get a free account, with additional paid for options being available):

Grammarly for Word

Grammarly for Chrome

Keywords in Content, Image Titles/Alt Attributes and Anchor Text

A simple one but one that, after a few hours of looking around the site and post-building up a new keyword strategy using Moz tools, we knew we could improve on.

We now have a much better spread of keywords across our pages, including LSI keywords (Latent Semantic Indexing); essentially just related phrases.

As for image titles and title/alt attributes, we went on a massive, night long, rampage to improve these; based on our new found keyword knowledge (using hyphens to separate words in resource names).

Lastly, a great deal of effort was placed upon using natural and informative text within anchor tags which, to be honest, we were a little weak on. This appears to have had a positive impact.

Sitemaps.xml

This one got me! I generated a sitemap that, on the face of it, looked prim and proper. However, after checking it in the Google Search Console I had been sucker punched by dodgy encoding (UTF-8 BOM, to be exact). There, at the start of my file, sat a Byte Order Mark (otherwise invisible in Notepad/Visual Studio, as these things often are). This equalled an instant red flag and is something worth not getting caught out on.

I found a reasonable looking Sitemaps.xml validator which flagged the issue:

Robots.txt Checker

Recreating the file in Notepad and checking it in fixed the issue (and doing the resubmit via Google Search Console).

One last thing (luckily I didn’t do this!), make sure to double check that in the robots.txt file you aren’t disallowing access to your entire site when it comes to¬†legitimate¬†bots. Thankfully, I was dead careful in this regard!

So, what has raised eyebrows (in the ‘why does this matter’ stakes)? One thing that has really got my goat is the¬†Flesch-Kincaid Reading Ease¬†score. I have spent a fair bit of time wracking my brains as to whether content really needs to be targeted at a¬†thirteen to the fifteen-year-old¬†student (when it comes to reading ability that is). In honesty, I’m not sure on this…

The content outlined in SEO 2016 references Searchmetrics findings show sites appearing in the top ten results, on average, have a Flesch reading score of 76.00; which puts a stake in the ground at the aforementioned thirteen to fifteen-year-old reading level ability.

This doesn’t sound all that bad to me; but, after some initial testing I was finding that our content was ranking below this bar on all¬†occasions. Not by too much, but enough to concern me. Upon testing some other comparable, higher ranking sites, I wasn’t able¬†to determine that any other site had much better¬†scores, to be honest.

We reread the content, multiple times, before coming to the conclusion that it was easy enough to read. I personally felt that certain sentences and words were being penalised too harshly for being ‘too complex’ or as having ‘too many¬†syllables’ when I’m sure that it could be easily read by children (far below the thirteen to fifteen-year-old mark).

It felt as though we had to dumb down our content to a point where it felt very unnatural; as if we couldn’t compose a sentence of more than five words. Possibly borderline insulting to most people; so we’ll be sticking to our guns for the time being.

What’s Next?

Claire and I have a few other strategies going on, such as getting some strong backlinks in play; this is the next port of call. We also need to focus more on the all-important social media. I have additional tasks to perform, such as adjusting how JavaScript is loaded (looking at async/defer options for all of my resources; without busting pages!), looking at resource bundling and caching including resource optimisation (i.e. a little bit more image compression work). I’ll be a busy bee for a fair while yet!

We’ll see how the first batch of alterations plays out first; it is incredibly difficult to shake the feeling that a good chunk of this is highly experimental!

If any SEO experts come across and can offer any further advice or would like to comment please do! I’d love to hear from you.

Until the next time, toodles!

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…