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

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

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

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

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

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

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

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

        private static SoundPlayer player = new SoundPlayer();

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

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

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

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

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

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

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

                    playFailSound = false;
                }

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

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

            } while (continuePlaying);
        }

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

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

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

            // The FINAL TEST!
            NavigateThroughTheFinalServingTest();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return complexItems;
        }

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

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

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

            Console.WriteLine();
        }

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

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

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

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

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

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

            return choiceValue;
        }

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

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

            return choice;
        }

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

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

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

            Console.WriteLine();
        }
    }

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

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

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

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

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

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

        }
    }

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

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

        }
    }

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

        }
    }
}

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

Gordon Ramsay Cooking Challenge.

Gordon Ramsay Cooking Challenge.

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

Claire Epic Failing.

Claire Epic Failing.

Claire Nailing It.

Claire Nailing It.

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

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

Gordon Ramsay Dash

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

Be a Dependency Injection Ninja with Ninject

Howdy all,

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

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

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

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

Program Structure

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

Overview of the Robot Factory Application by Class Diagram.

Robot Factory Application Class Diagram.

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

Program Class

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

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

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

        #endregion Private Static IKernel Ninject Container

        #region Main Application Entry Point

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

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

        #endregion Main Application Entry Point

        #region Ninject Static Configuration Method

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

        #endregion Ninject Static Configuration Methods

        #region Private Static Application Methods

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

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

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

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

            Console.ReadLine();
        }

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

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

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

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

                Console.WriteLine();
            });
        }

        #endregion Private Static Application Methods
    }
}

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

Ninject Nuget Package via the Nuget Package Manager.

Ninject Nuget Package.

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

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

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

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

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

Ninject Dependency Injection Module Configuration

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

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

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

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

        #endregion Overridden Load Method
    }
}

.....

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

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

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

        #endregion Overridden Load Method
    }
}

.....

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

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

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

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

        #endregion Overridden Load Method
    }
}

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

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

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

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

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

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

The Robot Factory

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

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

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

using System.Collections.Generic;

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

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

        #endregion Interface Properties

        #region Interface Methods

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

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

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

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

        #endregion Interface Methods
    }
}

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

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

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

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

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

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

        #endregion Private Fields

        #region Protected (Get) Properties

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

        #endregion Protected (Get) Properties

        #region Public Abstract Properties

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

        #endregion Public Abstract Properties

        #region Constructor

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

        #endregion Constructor

        #region IRobotFactory Interface Methods

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

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

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

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

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

            // Deploy!
            return robotsToDeploy;
        }

        #endregion IRobotFactory Interface Methods
    }
}

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

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

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Public Overridden Properties

        #region Constructor

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

        }

        #endregion Constructor
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Public Overridden Properties

        #region Constructor

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

        }

        #endregion Constructor
    }
}

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

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

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

        #endregion Interface Methods
    }
}

.....

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

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

        #endregion Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Private Constants

        #region Public IPainter Interface Methods

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

        #endregion Public IPainter Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Private Constant

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

.....

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Private Constants

        #region Public IWeaponAttacher Interface Methods

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

        #endregion Public IWeaponAttacher Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        #endregion Private Constants

        #region Public IWeaponAttacher Interface Methods

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

        #endregion Public IWeaponAttacher Interface Methods
    }
}

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

The Robots

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

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

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

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

        #endregion Interface Properties

        #region Interface Methods

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

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

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

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

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

        #endregion Interface Methods
    }
}

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

Time for the Robot abstract base class then:

using System;
using RobotArmyProcessingLine.Interface;

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

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

        #endregion Protected Properties

        #region Public (Get) Properties

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

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

        #endregion Public (Get) Properties

        #region Constructor

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

            MessageOutputter = outputter;
        }

        #endregion Constructor

        #region Public Abstract IRobot Interface Methods

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

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

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

        #endregion public abstract IRobot Interface Methods

        #region Public IRobot Interface Methods

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

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

        #endregion Public IRobot Interface Methods
    }
}

Bit by bit then…

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

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

using RobotArmyProcessingLine.Interface;

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

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

        }

        #endregion Constructor

        #region IRobot Interface Methods

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

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

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

        #endregion IRobot Interface Methods

        #region ISmallRobot Interface Methods

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

        #endregion ISmallRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        }

        #endregion Constructor

        #region IRobot Interface Methods

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

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

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

        #endregion IRobot Interface Methods

        #region ISmallRobot Interface Methods

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

        #endregion ISmallRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        }

        #endregion Constructor

        #region IRobot Interface Methods

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

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

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

        #endregion IRobot Interface Methods

        #region ILargeRobot Interface Methods

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

        #endregion ILargeRobot Interface Methods
    }
}

.....

using RobotArmyProcessingLine.Interface;

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

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

        }

        #endregion Constructor

        #region IRobot Interface Methods

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

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

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

        #endregion IRobot Interface Methods

        #region ILargeRobot Interface Methods

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

        #endregion ILargeRobot Interface Methods
    }
}

.....

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

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

        #endregion Interface Methods
    }
}

.....

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

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

        #endregion Interface Methods
    }
}

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

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

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

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

        #endregion Interface Methods
    }
}

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

using RobotArmyProcessingLine.Interface;
using System;

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

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

        #endregion IRobotOutputter Interface Methods
    }
}

.....

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

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

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

        #endregion IRobotOutputter Interface Methods
    }
}

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

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

Running the Program

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

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

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

Large Robot Factory Constructor Debugging.

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

Small Robot Constructor debugging showing concrete types being passed in.

Small Robot Constructor Debugging.

Large Robot Constructor debugging showing concrete types being passed in.

Large Robot Constructor Debugging.

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

Robot factory application output in full.

Robot Factory Application Output.

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

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

Ninject Documentation

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

All the best and until the next time!

The Importance of Being Lazy

Firstly, apologies are in order…I couldn’t resist the incredibly cheesy title. Secondly, this post has absolutely nothing to do with being lazy (a trait I’m sure is attached to us developers on a regular basis, ahem!), in the traditional sense at least. Nope, today we’ll be looking at the lazy keyword in C# and trying to get an understanding as to how it can be used.

A ‘Lazy’ Explanation

Right, that was the last crap joke and attempt to poke fun at the term ‘lazy’, I promise! So what does this keyword entail and how is it used? The most rudimentary packaged answer is that it allows the developer the necessary control to defer the creation of an ‘expensive’ object (or delay a resource intensive operation) until required by calling code. You may, for example, have a property within one of your classes that although a perfectly valid member (i.e. has a rightful place within the object) may only rarely be required by other members utilising this object. If you couple this with the fact that this object property, hypothetically, at least, is very expensive to create (i.e. a large list or array, a dataset requiring interaction with a database, etc.) then you may find the lazy keyword useful. Here are some further key points to give you a solid grounding in the basics:

  • When used in the appropriate context you can open up opportunities to increase application performance and reduce memory requirements (with the added bonus of easing the pressure on the garbage collector).
  • Allows you to avoid unrequired computations. It’s worth noting here that anything created using the lazy keyword operates on a single instance basis (i.e. you always get returned the same object or value used to initialise the member you are accessing). Examples of this in action are coming right up, so hold on to your hats.
  • Getting access to a lazy members value is, unsurprisingly, achieved via using the ‘.Value’ property (e.g. from the get accessor of a property). More on this later again.
  • Interactions with objects instantiated using the lazy keyword are, by default, thread-safe. There are a few extra discussion points to cover here, which will follow shortly.
  • Ability to write lambdas and use anonymous methods to instantiate a member, writing complex initialisation logic as needed.

I want to scratch the surface on a couple of these points before we proceed to the examples; mainly as I feel a bit more of a detailed discussion wouldn’t go amiss. Firstly, after a root around by myself and a friend at work, the default implementation of a lazy objects thread-safety mechanic (as hinted at in the MSDN documentation) seems to be potentially resource intensive (although hopefully wouldn’t rival the overhead of the objects you intend to work with using this method!). Also, there is the possibility of deadlocks to contend with, albeit a fairly small chance. As we stood on the edge of the diving board and took the plunge, we quickly realised (we did a bit of decompiling to discover this) that thread safety, as far the lazy class goes, involves a fair few lines of code and the utilisation of Monitor.Enter. The end result here is that, depending on usage, you actually may find that you want to alter how locks on lazy objects work (no fast and hard evidence of course, I’m just making you aware of the information should you want to delve deeper and make a more informed decision further down the line).

As an alternative, you can use a constructor consuming a LazyThreadSafetyMode enum value and passing LazyThreadSafetyMode.PublicationOnly through as the value. This provides an alternative strategy to the default locking, whereby all threads ‘race’ to initialise the value (when a member is called simultaneously). One thread initialises the value, and all other threads receive a copy of the ‘same’ object, again only if the ‘Value’ property is called at the same time by multiple threads. Instances created, that ultimately don’t get used, are discarded. As eluded to on MSDN, the end result here is that you mitigate the locking overhead but run the risk of creating and discarding extra copies of an object that is expensive to create (again, it’s stated that this eventuality is unlikely). The end result here is to take all of this onboard and choose your path wisely (a little like picking the right cup in Indiana Jones and the Last Crusade, hopefully without the same severe consequences!).

Something else that could potentially catch you out is, when you use factory methods to initialise a lazy object, that exceptions are cached. In essence, if an exception is thrown the first time a thread accesses a lazy objects Value property this same exception will continue to be thrown on every call (even if conditions change that would otherwise result in a successful call further down the line). This protects us against scenarios whereby we could get subtly different results on different threads and introduces the consistency of ‘on every call, you get the same result’, something which certainly makes sense. A poignant point to be aware of at the very least. MSDN states to add retry logic into the instantiation routine (e.g. the factory method); add this concept to the kit bag at any rate.

Hopefully, this gives you an idea that this, conceptually, can be incredibly useful; with the potential, of course, to lead you quickly up shit creek if you’re not on the ball! For you further delvers and divers, here’s the MDSN documentation to keep you busy:

MDSN Lazy Class Documentation
MSDN Lazy Initialisation

Basic Lazy Usage Examples

We’ve discussed many of the finer points above, so I’ll make sure I’m sticking to business here and will try to keep this as short, and sweet, as possible.

To start us off, we have a basic outline of an Applicant class with some properties and a constructor. Simulating our ‘expensive-to-create’ member, in this case, is the ApplicantExtraDetails object. This has a private backing field and is accessible via a public property. In this implementation, the private backing field for our ApplicantExtraDetails (we could have had a normal property, initialised in the constructor, of course, but I’ve structured it this way for an easier swap out later) is ‘always’ created, regardless of whether calling code uses it.

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

namespace LazyObjects
{
    /// <summary>
    /// Class that outlines a basic job applicant.
    /// </summary>
    public class Applicant
    {
        #region Public Properties

        /// <summary>
        /// Gets the applicants unique identifier (to be set
        /// via the constructor).
        /// </summary>
        public Guid UniqueApplicantIdentifier { get; }

        /// <summary>
        /// Gets or sets the applicants forename.
        /// </summary>
        public string Forename { get; private set; }

        /// <summary>
        /// Gets or sets the applicants surname.
        /// </summary>
        public string Surname { get; private set; }

        /// <summary>
        /// Gets or sets the applicants core skills.
        /// </summary>
        public List<string> CoreSkills { get; private set; }

        #endregion Public Properties

        #region Expensive Field/Property

        /// <summary>
        /// Private data field that outlines an applicants extra details (a mock object only,
        /// not best practice, just for illustration). Container for other objects.
        /// </summary>
        private ApplicantExtraDetails extraDetails = new ApplicantExtraDetails();

        /// <summary>
        /// Gets the applicants extra details (expensive object to retrieve
        /// and/or hold in memory). May not be required by the caller.
        /// </summary>
        public ApplicantExtraDetails ExtraDetails
        {
            get
            {
                return extraDetails;
            }
        }

        #endregion Expensive Field/Property

        #region Constructor

        /// <summary>
        /// Initialises a new instance of the Applicant class with standard setup data.
        /// </summary>
        /// <param name="uniqueIdent">The applicants unique identifier.</param>
        /// <param name="firstName">The applicants first name.</param>
        /// <param name="lastName">The applicants surname.</param>
        /// <param name="skills">The applicants skills (basic).</param>
        public Applicant(Guid uniqueIdent, string firstName, string lastName, params string[] skills)
        {
            UniqueApplicantIdentifier = uniqueIdent;
            Forename = firstName;
            Surname = lastName;
            CoreSkills = skills.ToList();
        }

        #endregion Constructor
    }
}

Rolling on, here we have the ApplicantExtraDetails type itself, which contains two arrays (that could be, but aren’t, massive) that can hold PersonalInterest and OtherDetail objects respectively.

using System;

namespace LazyObjects
{
    /// <summary>
    /// Class that outlines a job applicant extra details (that may not always be 
    /// required by the caller).
    /// </summary>
    public class ApplicantExtraDetails
    {
        #region Private Data Fields

        /// <summary>
        /// Private data field that outlines an applicant’s personal interests (a mock object only,
        /// not best practice, just for illustration).
        /// </summary>
        private PersonalInterest[] personalInterests = new PersonalInterest[2] { new PersonalInterest(), new PersonalInterest() };

        /// <summary>
        /// Private data field that outlines an applicant’s other details (a mock object only,
        /// not best practice, just for illustration). 
        /// </summary>
        private OtherDetail[] otherDetails = new OtherDetail[2] { new OtherDetail(), new OtherDetail() };

        #endregion Private Data Fields

        #region Public Properties

        /// <summary>
        /// Gets an applicant’s personal interests.
        /// </summary>
        public PersonalInterest[] PersonalInterests
        {
            get
            {
                return personalInterests;
            }
        }

        /// <summary>
        /// Gets an applicant’s other details.
        /// </summary>
        public OtherDetail[] OtherDetails
        {
            get
            {
                return otherDetails;
            }
        }

        #endregion Public Properties

        #region Constructor

        /// <summary>
        /// Initialises a new instance of the ApplicantExtraDetails class with standard setup data.
        /// </summary>
        public ApplicantExtraDetails()
        {
            // Log when this class gets instantiated for illustration purposes
            Console.WriteLine("Applicant Extra Details instantiated!{0}", Environment.NewLine);
        }

        #endregion Constructor
    }
}

The PersonalInterest and OtherDetail classes themselves just contain a single string property, for illustration only, during the upcoming example.

namespace LazyObjects
{
    /// <summary>
    /// Class that outlines a job applicant personal interest (that may not always be 
    /// required by the caller - Part of the ApplicantExtraDetails).
    /// </summary>
    public class PersonalInterest
    {
        #region Getter Only Auto Property

        /// <summary>
        /// Gets the value associated with this 
        /// personal interest (hard coded for illustration).
        /// </summary>
        public string Value => "Test Personal Interest.";

        #endregion Getter Only Auto Property
    }
}

...

namespace LazyObjects
{
    /// <summary>
    /// Class that outlines a job applicant 'other detail' (that may not always be 
    /// required by the caller - Part of the ApplicantExtraDetails).
    /// </summary>
    public class OtherDetail
    {
        #region Getter Only Auto Property

        /// <summary>
        /// Gets the value associated with this 
        /// other detail (hard coded for illustration).
        /// </summary>
        public string Value => "Test Other Detail.";

        #endregion Getter Only Auto Property
    }
}

So, on to the Console Application program class that brings some of this code into scope. For starters, we generate a couple of applicants using fixed values and then add these applicants to a list for iterative processing. The crux during this iterative processing is that only the second applicants ‘Extra Details’ ultimately get interrogated and extracted in this sample…output coming up next.

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

namespace LazyObjects
{
    /// <summary>
    /// Console program class (for a Lazy Objects test).
    /// </summary>
    class Program
    {
        /// <summary>
        /// Main entry point method.
        /// </summary>
        /// <param name="args">Arguments passed to this application.</param>
        static void Main(string[] args)
        {
            // Generate two unique identifiers for our applicants
            Guid applicantOneUniqueReference = Guid.NewGuid(), applicantTwoUniqueReference = Guid.NewGuid();

            // Generate two test 'applicants' - This data, along with the identifiers, would have been sourced from a database in this example (just hard coded for reference)
            Applicant applicantOne = new Applicant(applicantOneUniqueReference, "James", "Jones", new string[] { "C#", "F#", "C++" }), 
                applicantTwo = new Applicant(applicantTwoUniqueReference, "Brenda", "Reed", new string[] { "HTML", "CSS", "jQuery" });

            // Start processing the applicants...
            Console.WriteLine("Processing applicants...{0}", Environment.NewLine);

            // Doing a foreach to rip out the firstname/surname of each applicant
            List<Applicant> applicants = new List<Applicant>();
            applicants.AddRange(new Applicant[] { applicantOne, applicantTwo });
            applicants.ForEach(app => 
            {
                Console.WriteLine("Firstname: {0}", app.Forename);
                Console.WriteLine("Surname: {0}{1}", app.Surname, Environment.NewLine);

                // Only get and process the 'expensive details' for applicant two
                if (app.UniqueApplicantIdentifier == applicantTwoUniqueReference)
                {
                    app.ExtraDetails.PersonalInterests.ToList().ForEach(item => Console.WriteLine(item.Value));
                    Console.WriteLine();

                    app.ExtraDetails.OtherDetails.ToList().ForEach(item => Console.WriteLine(item.Value));
                    Console.WriteLine();
                }
            });

            // Finished this processing run
            Console.WriteLine("Finished processing...");
            Console.ReadLine();
        }
    }
}

Due to a little logging placed in the constructor of the ApplicantExtraDetails, you can clearly see here that (as we fully expect) both applicants have initialised an object that is not always required.

Console output from a test using no Lazy objects.

Test Using No Lazy Objects.

Ok, a no brainer I hear you say; bread and butter examples always provide a good ‘base camp’ to start from, though. So the problem here is that the object representing the first applicant has been backed into a corner whereby it has been forced to create an ApplicantExtraDetails object on type initialisation, even though only the second applicants ApplicantExtraDetails object property is being used. Let’s change it up to be a little lazier.

Using Lazy Object Instantiation

A minor change has been made to the implementation of the Applicant class to use the generic lazy type. The key thing to note here is that, with the ExtraDetails property, you need to call the ‘.Value’ property to actually obtain the relevant details to return to the caller.

#region Expensive Field/Property

/// <summary>
/// Private data field that outlines an applicant’s extra details (a mock object only,
/// not best practice, just for illustration). Container for other objects. Now using
/// full, Lazy instantiation.
/// </summary>
private Lazy<ApplicantExtraDetails> extraDetails = new Lazy<ApplicantExtraDetails>();

/// <summary>
/// Gets the applicants extra details (expensive object to retrieve
/// and/or hold in memory). May not be required by the caller. Note the 
/// use of .Value now (since the backing field utilised Lazy<T>)./>
/// </summary>
public ApplicantExtraDetails ExtraDetails
{
	get
	{
		return extraDetails.Value;
	}
}

#endregion Expensive Field/Property

The end result is illustrated here, whereby we used exactly the same program class listing above. Two things to note…firstly, notice that the ‘Applicant Extra Details instantiated’ only occurs once, for our second applicant, which is bonza. However, you should also pick up on the fact that the logging of this message now occurs further ‘down the road’ in the application’s lifetime, a nod to the fact that the creation of the object was deferred until it was required.

Console output from a test using Lazy objects.

Test Using Lazy Objects.

For our last wheel spin and handbrake turn, take a look at the last example showing initialisation of a lazy field, using an anonymous method (i.e. factory method) to create the goods.

/// <summary>
/// Example of a static lazy data field.
/// </summary>
private static Lazy<List<string>> lazyStringList = new Lazy<List<string>>(() =>
{
	Console.WriteLine("Getting lazyStringList Value!{0}", Environment.NewLine);

	List<string> newLazyList = new List<string>();
	newLazyList.AddRange(new string[] { "Test one", "Test two", "Test three" });

	return newLazyList;
});

/// <summary>
/// Main entry point method.
/// </summary>
/// <param name="args">Arguments passed to this application.</param>
static void Main(string[] args)
{
	LazyListTest();
}

/// <summary>
/// Lazy static data field test.
/// </summary>
private static void LazyListTest()
{
	// Initialise a couple of lists (initialisation, as the lazy field is static, will occur only once (returns a reference to the same object))
	List<string> testOne = lazyStringList.Value, testTwo = lazyStringList.Value;

	// Iterate over both lists, using an extension
	Console.WriteLine("Iterating over testOne values:");
	testOne.ListItemsToConsole();

	Console.WriteLine("{0}Iterating over testTwo values:", Environment.NewLine);
	testTwo.ListItemsToConsole();

	Console.ReadLine();
}

...

using System;
using System.Collections.Generic;

namespace LazyObjects
{
    /// <summary>
    /// Static extensions class, for illustration only.
    /// </summary>
    public static class Extensions
    {
        /// <summary>
        /// Pushes list items to the console.
        /// </summary>
        /// <param name="targetList">The List to operate on (of the type specified, would not to restrict by type a little more in the real world).</param>
        public static void ListItemsToConsole<T>(this List<T> targetList)
        {
            // We could throw an exception here alternatively, if the list was not correctly instantiated - Preference here just to skip over however
            if (targetList != null && targetList.Count > 0)
            {
                targetList.ForEach(item => Console.WriteLine(item));
            }
        }
    }
}

Here’s the output. The thing to run with here is that the testOne and testTwo lists have both been set using lazyStringList.Value but the factory method initialising lazyStringList was only called once. Remember lazy objects are accessed via the ‘.Value’ property as read-only essentially and the same object is returned on subsequent calls.

Console output from a test using Lazy objects statically.

Test Using Lazy Objects Statically.

I hope this has been a useful tour de force on the subject of lazy objects and, as always, happy coding until the next time!

When are Injections Fun? C# Dependency Injection Deep Dive

Evening all,

This post has been in the works for a while but, due to a wee bit of sickness and a sudden busy schedule outside of work, it’s been waiting in the wings for a little longer than it should have been. Apologies about that guys and girls!

Anyway, I wanted to expose a piece on Dependency Injection. There has been an ongoing slice of development, using this methodology, doing the rounds at work. However, I wanted to look at DI from the perspective of Containers (DI can exist without these, but I’m interested solely in this approach for the time being) and will be using Autofac as the showcase for this.

Dependency Injection In A Nutshell

Dependency Injection essentially encapsulates the idea of producing loosely-coupled, easily testable code whereby classes are not (in the case of coupling DI with interface usage) tied to each other using concrete types. Using a DI Container, it’s also possible for the caller to request an implementation via an interface and retrieve an object on demand, without the need to worry about what other dependencies the type requested may require. When things are interface-centric, it’s also a cinch to override implementations and, off the back of this, unit test specific type behaviour in a more isolated way.

The best explanation you’ll find, without a shadow of a doubt, is this one (enjoy!):

How to explain dependency injection to a 5-year-old?

When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired.

What you should be doing is stating a need, “I need something to drink with lunch,” and then we will make sure you have something when you sit down to eat.

Dependency Injection Sample

What follows is a fairly trivial application that implements an Autofac DI Container, and shows off a few basic DI concepts to boot. Firstly, here are the resources that I used to kick start this project:

Autofac Documentation
Autofac NuGet Gallery Reference

I found this particular TechEd video particularly interesting. It covers DI and Container usage from the perspective of Autofac, Unity and many others (although, leans more towards Autofac as the examples begin to get more fleshed out):

Deep Dive into Dependency Injection and Writing Decoupled Quality Code and Testable Software

This first snippet of code outlines the entry point for a small Console Application. The ConfigureApplicationContext method constructs a ContainerBuilder object, which is part of the Autofac namespace, using a RegisterApplicationTypes helper method. This method illustrates, on application start, the linking of interface types to concrete implementations. Notice the addition of the ‘SingleInstance’ call against the registration of the IConfigurationHelper implementing type, this is an interesting nugget that forces the same instance of a class, as opposed to a new instance, to be retrieved when required (via a request to the DI Container).

The FileCleaner classes Run method is then called (I’ve used a concrete type at this level but, of course, I could have referenced this via an interface also). The FileCleaner class constructor accepts, for the purposes of resolving types from the DI Container, an IProcessorLocator implementing object. You’ll see this isn’t passed in per say, the call to Application.Container.Resolve takes care of this ‘dependency’ for use, magic! You’ll see how the IProcessorLocator object gets used specifically in later examples (the comments here also expand on the concepts at work, so be sure to have a sift through).

using Autofac;
using DesktopCleaner.Helpers;
using DesktopCleaner.Implementations;
using DesktopCleaner.Interfaces;
using DesktopCleaner.Locators;
using System;

namespace DesktopCleaner
{
    /// <summary>
    /// Console Application Program Class, containing this applications
    /// entry point (Main) method.
    /// </summary>
    class Program
    {
        #region Constructor

        /// <summary>
        /// Static Main method representing this applications
        /// entry point.
        /// </summary>
        /// <param name="args">Any arguments from external sources.</param>
        static void Main(string[] args)
        {
            // Configure this applications DI Container
            ConfigureApplicationContext();
        }

        #endregion Constructor

        #region Private Static Helper Methods

        /// <summary>
        /// Private static helper method that configures this applications
        /// DI Container fully, ready for the applications life-time (as well
        /// as kicking off the core processing of this application via a FileCleaner instance).
        /// </summary>
        private static void ConfigureApplicationContext()
        {
            // Use the Autofac ContainerBuilder type to construct interface/concrete type mappings
            ContainerBuilder builder = RegisterApplicationTypes();

            // Construct our DI Container (for general use throughout the lifetime of our application in this case)
            Application.Container = builder.Build();

            // Create a cleanerHelper and 'run it' (the objects constructor will receive an IProcessLocator implementing object (ProcessorLocator) in this case due to the previous mappings)
            FileCleaner cleanOperationHelper = Application.Container.Resolve<FileCleaner>();
            if (cleanOperationHelper.Run())
            {
                Console.WriteLine("Cleaning Completed Successfully!");
            }
            else
            {
                Console.WriteLine("Cleaning Failed. Please check the logs (what a joke, there are none!).");
            }

            // Halt application before exit so we can inspect the output
            Console.ReadLine();
        }

        /// <summary>
        /// Private static helper method that creates a ContainerBuilder
        /// to map interfaces to concrete types (for DI loveliness). Return the builder
        /// to the caller (we're using this to called builder.Build() to setup our 'Container').
        /// </summary>
        /// <returns></returns>
        private static ContainerBuilder RegisterApplicationTypes()
        {
            // Instantiate a builder and map types as required
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<FileCleaner>();
            builder.RegisterType<ConfigurationHelper>().As<IConfigurationHelper>().SingleInstance();    // A special case here, demonstrate the use of SingleInstance()
            builder.RegisterType<FileHelper>().As<IFileHelper>();
            builder.RegisterType<ProcessorLocator>().As<IProcessorLocator>();                           // A cool little utility to get instances (so we don't have to new-up in classes using concrete types)

            return builder;
        }

        #endregion Private Static Helper Methods
    }
}

Absolutely not required, just for illustration purposes only, the following static class is simply used as an application level helper (for global access to the container). Not necessarily how you’d structure it, but makes the examples coming up easier to manoeuvre through.

using Autofac;

namespace DesktopCleaner.Helpers
{
    /// <summary>
    /// Public static class that holds application constants
    /// and shared helpers.
    /// </summary>
    public static class Application
    {
        #region Public Static Properties (CORE DI CONTAINER)

        /// <summary>
        /// Public static property (for use across this application
        /// </summary>
        public static IContainer Container { get; set; }

        #endregion Public Static Properties (CORE DI CONTAINER)

        #region Public Constants

        /// <summary>
        /// Public constant string representing the DesktopAppSettingKey
        /// key value (in the app.config).
        /// </summary>
        public const string DesktopAppSettingKey = "DesktopPath";

        #endregion Public Constants
    }
}

Next up, we need some interfaces. These represent key processes that our application is expected to implement (the catch being that these interfaces will be used to retrieve concrete implementations on demand, without the need to use the ‘new’ keyword in our classes). Note the last interface in this list, IProcessorLocator. Again, this is a linchpin type that will be passed to each class to retrieve all manner of other types (due to its use of a generic method) on demand. The result being here that using an IProcessorLocator, as a container wrapper, negates the need to pass multiple interfaces to a type’s constructor. We just pass this one interface supporting object instead (and this also means we don’t need data fields to store these instances either).

namespace DesktopCleaner.Interfaces
{
    /// <summary>
    /// Public ICleanerHelper support interface definition.
    /// </summary>
    public interface ICleanerHelper
    {
        #region Interface Methods

        /// <summary>
        /// Public method for ICleanerHelper support representing
        /// behaviour for a 'run' process method.
        /// </summary>
        /// <returns>True if the run processing is successful, otherwise false.</returns>
        bool Run();

        #endregion Interface Methods
    }
}

...

using System.Collections.Specialized;

namespace DesktopCleaner.Interfaces
{
    /// <summary>
    /// Public ICleanerHelper support interface definition.
    /// </summary>
    public interface IConfigurationHelper
    {
        #region Interface Methods

        /// <summary>
        /// Public method for IConfigurationHelper support to allow for behaviour
        /// to retrieve a 'setting' based on a 'key'.
        /// </summary>
        /// <param name="key">The key to transpose to a value.</param>
        /// <returns>The value that links to the specified key.</returns>
        string GetConfigurationSetting(string key);

        /// <summary>
        /// Public method for IConfigurationHelper support to allow for behaviour
        /// to retrieve a collection of 'setting' keys and values.
        /// </summary>
        /// <returns>A collection of settings (specialised NameValueCollection).</returns>
        NameValueCollection GetAllConfigurationSettings();

        #endregion Interface Methods
    }
}

...

using System.Collections.Generic;

namespace DesktopCleaner.Interfaces
{
    /// <summary>
    /// Public IFileHelper support interface definition.
    /// </summary>
    public interface IFileHelper
    {
        #region Interface Methods

        /// <summary>
        /// Public method for IFileHelper support to allow for behaviour
        /// to get a list of files based on the specified path (in some manner, based on implementation).
        /// </summary>
        /// <param name="path">The directory path to be used.</param>
        /// <returns>A list of files relating to the directory specified.</returns>
        List<string> GetFilesForPathAsList(string path);

        /// <summary>
        /// Public method for IFileHelper support to allow for behaviour
        /// to process a list of file names (in some manner, based on implementation). 
        /// </summary>
        /// <param name="fileList">Represents the list of files to operate on.</param>
        /// <returns>A boolean to represent if processing was successful.</returns>
        bool ProcessFiles(List<string> fileList);

        #endregion Interface Methods
    }
}

...

namespace DesktopCleaner.Interfaces
{
    /// <summary>
    /// Public IProcessorLocator support interface definition.
    /// </summary>
    public interface IProcessorLocator
    {
        #region Interface Methods

        /// <summary>
        /// Public method for IProcessorLocator support to allow for behaviour
        /// to get a 'processor' for any specified interface type (this should be constrained more
        /// in an ideal world).
        /// </summary>
        /// <typeparam name="T">The type to retrieve a processor class based on.</typeparam>
        /// <returns>A concrete class, depending on the implementation.</returns>
        T GetProcessor<T>();

        #endregion Interface Methods
    }
}

Here we have another ‘illustrative’ class that, as you’ll remember from our DI Container configuration, is marked as ‘Single Instance’ (just as an example). It simply interrogates the AppSettings of the app.config file to retrieve information, as required by calling code.

using DesktopCleaner.Interfaces;
using System.Collections.Specialized;
using System.Configuration;

namespace DesktopCleaner.Implementations
{
    /// <summary>
    /// Public ConfigurationHelper class that implements IConfigurationHelper
    /// to interrogate the applications app.config file (implementation can
    /// be modified however, as per the DesktopCleaner.UnitTests).
    /// </summary>
    public class ConfigurationHelper : IConfigurationHelper
    {
        #region Public Expression Bodied Methods

        // Again, illustration only, may abstract this into a differing format (use of lazy/properties, etc) - Methods are for demo purposes (for mocking up a functional class for DI usage)

        /// <summary>
        /// Gets access to the applications app.config AppSetting
        /// key/value pairs (as is).
        /// </summary>
        /// <returns></returns>
        public NameValueCollection GetAllConfigurationSettings() => ConfigurationManager.AppSettings;

        /// <summary>
        /// Gets access to the a particular AppSetting value, from the app.config
        /// file, based on the provided key.
        /// </summary>
        /// <param name="key">The AppSetting key to use when searching for a corresponding value.</param>
        /// <returns>A string denoting the matching value (based on key).</returns>
        public string GetConfigurationSetting(string key) => ConfigurationManager.AppSettings[key];

        #endregion Public Expression Bodied Methods
    }
}

The next couple of classes represent the bulk of our test application. There is nothing super special or uber magical here, so it should be easy to stick with. The idea behind this application is to move files from one location to another, tidying files after a successful move. This is all tied to configuration found in the app.config (which can, of course, be overridden as demonstrated later on by some example unit tests). Due to the use of interfaces, the implementation itself could differ greatly, however.

The key code lies in the constructor, that assigns a private data field with an object supporting the IProcessorLocator interface, allowing for type resolution in the other core methods in this class. Within the Run method the ‘processor locator’ is finally utilised to, on demand, locate and retrieve instances of IConfigurationHelper and IFileHelper supporting objects. We could, of course, have foregone the use of the ProcessLocator, and passed in all required interface types into this objects constructor. However, we would have incurred penalties for unrequired object creation and storage for types that, in reality, may not even be used by calling code (in this example I’m utilising all of the types anyway, but just mark it as a side note!). We have an example of some loosely-coupled code!

The CompareObjectsInDebug method is there just to illustrate that the call to processorLocator.GetProcessor is retrieving new objects/single instances as expected.

using DesktopCleaner.Helpers;
using DesktopCleaner.Interfaces;
using System;

namespace DesktopCleaner.Implementations
{
    /// <summary>
    /// Public class that represents a 'File Cleaner', supporting
    /// a Run method for processing and cleaning desktop files.
    /// </summary>
    public class FileCleaner : ICleanerHelper
    {
        #region Private Data Fields

        /// <summary>
        /// Private data field that represents this types processor locator (that
        /// will contain an instance of a class implementing this interface for 
        /// grabbing concrete types to perform operations.
        /// </summary>
        private IProcessorLocator processorLocator;

        #endregion Private Data Fields

        #region Constructor

        /// <summary>
        /// Instantiates a new FileCleaner object; Autofac deals with
        /// the passing of an IProcessorLocator supporting object (or Moq
        /// handles this when Unit Tests are involved).
        /// </summary>
        /// <param name="locator">An IProcessorLocator implementing object (for this class to support various forms of functionality).</param>
        public FileCleaner(IProcessorLocator locator)
        {
            processorLocator = locator;
        }

        #endregion Constructor

        #region Public Methods

        /// <summary>
        /// Public method that performs the core operation of this class. We obtain 
        /// information from the app.config, retrieve files from the designated desktop
        /// location and process them (i.e. copy to a set location and delete the originals).
        /// </summary>
        /// <returns>A boolean that denotes if this operation completed successfully.</returns>
        public bool Run()
        {
            Console.WriteLine("Running the cleaner helper!");

            // Use this instances IProcessLocator supporting object to get instances of classes supporting the IConfigurationHelper and IFileHelper interfaces
            // for retrieving files and subsequently processing them
            IConfigurationHelper configurationHelper = processorLocator.GetProcessor<IConfigurationHelper>();
            IFileHelper fileHelper = processorLocator.GetProcessor<IFileHelper>();

#if DEBUG
            // In debug, performing a little extra output logging to illustrate object setup (The IConfigurationHelper implementing object is set up as 'Single Instance', so we want to illustrate this)
            CompareObjectsInDebug(configurationHelper, fileHelper);
#endif

            // We have our objects, now run the 'process' and see if it completes successfully
            bool operationSuccessful = false;

            try
            {
                operationSuccessful = fileHelper.ProcessFiles(fileHelper.GetFilesForPathAsList(configurationHelper.GetConfigurationSetting(Application.DesktopAppSettingKey)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return operationSuccessful;
        }

        #endregion Public Methods

        #region Private Helper Methods

        /// <summary>
        /// Private helper method that does a little bit of extra object
        /// interrogation and output, in debug mode, to show object configuration.
        /// </summary>
        /// <param name="configurationHelper">The IConfigurationHelper object passed from the caller (for comparison).</param>
        /// <param name="fileHelper">The IFileHelper object passed from the caller (for comparison).</param>
        private void CompareObjectsInDebug(IConfigurationHelper configurationHelper, IFileHelper fileHelper)
        {
            Console.WriteLine();

            // Create two new objects using the process locator - We want to see if the IConfigurationHelper supporting object is Single Instance, as opposed to the IFileHelper supporting object
            IConfigurationHelper configurationHelper2 = processorLocator.GetProcessor<IConfigurationHelper>();
            IFileHelper fileHelper2 = processorLocator.GetProcessor<IFileHelper>();

            // What are dealing with (additional debug info only) - Actual do the object interrogation; first on Hash Codes
            Console.WriteLine("configurationHelper HashCode: {0}", configurationHelper.GetHashCode());
            Console.WriteLine("configurationHelper2 HashCode: {0}", configurationHelper2.GetHashCode());
            Console.WriteLine("fileHelper HashCode: {0}", fileHelper.GetHashCode());
            Console.WriteLine("fileHelper HashCode: {0}", fileHelper2.GetHashCode());

            // ...Then on an actual 'equals' check
            Console.WriteLine("configurationHelper == ConfigurationHelper2: {0}", configurationHelper == configurationHelper2);
            Console.WriteLine("fileHelper == fileHelper2: {0}", fileHelper == fileHelper2);

            Console.WriteLine();
        }

        #endregion Private Helper Methods
    }
}

The next class, apart from being an example of very, very incomplete exception handling (gulp!) shows a similar pattern to the above class again. The IProcessorLocator object is passed in, as a dependency, to this object’s constructor (when it is resolved and retrieved by an object that requires it) and then utilised to retrieve types to perform the relevant class functions as needed.

This is essentially the workhorse class, handling files, performing the move and delete operations and then reporting the result (in the form of a boolean) to the caller. I’ve utilised a couple of private helper methods, just as processing aids (which could be changed as required/exposed also as public implementations to be overridden).

using DesktopCleaner.Helpers;
using DesktopCleaner.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DesktopCleaner.Implementations
{
    /// <summary>
    /// Public class that represents a 'File Helper', supporting
    /// various methods for obtaining files and cleaning directories.
    /// </summary>
    public class FileHelper : IFileHelper
    {
        #region Private Data Fields

        /// <summary>
        /// Private data field that represents this types processor locator (that
        /// will contain an instance of a class implementing this interface for 
        /// grabbing concrete types to perform operations.
        /// </summary>
        private IProcessorLocator processorLocator;

        #endregion Private Data Fields

        #region Constructor

        /// <summary>
        /// Instantiates a new FileHelper object; Autofac deals with
        /// the passing of an IProcessorLocator supporting object (or Moq
        /// handles this when Unit Tests are involved).
        /// </summary>
        /// <param name="locator">An IProcessorLocator implementing object (for this class to support various forms of functionality).</param>
        public FileHelper(IProcessorLocator locator)
        {
            processorLocator = locator;
        }

        #endregion Constructor

        #region Public Methods

        /// <summary>
        /// Public method that, based on a provided path, will return
        /// files in the given directory in the form of a List<string>.
        /// </summary>
        /// <param name="path">The path to return files for.</param>
        /// <returns>A list of type string representing files in the given directory.</returns>
        public List<string> GetFilesForPathAsList(string path)
        {
            // Two phases of validation here. Ensure the path provided is set and is valid (treating these as both exceptional circumstances in my scenario, could be debated of course)
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (!Directory.Exists(path))
            {
                throw new InvalidOperationException("GetFilesForPathAsList called with a path that does not resolve to a valid directory");
            }

            // Attempt to set the directoryFileList so the data can be returned to the caller
            List<string> directoryFileList = null;

            try
            {
                directoryFileList = Directory.GetFiles(path).ToList();
            }
            catch (Exception ex)
            {
                // TODO (LOL!) - Log
                Console.WriteLine(ex.Message);
            }
            
            return directoryFileList;
        }

        /// <summary>
        /// Public method that serves as the main work-horse for this class.
        /// We consume a file list and, based on app.config AppSetting pathing information,
        /// decided on where to copy files based on extensions (subsequently deleting them from
        /// the original file location after copy).
        /// </summary>
        /// <param name="fileList">The list of files to operate on.</param>
        /// <returns>A boolean representing if the process was a success (fails on first error in its current form).</returns>
        public bool ProcessFiles(List<string> fileList)
        {
            // Phase one validation only, just ensure the file list is set correct (i.e. not null)
            if (fileList == null)
            {
                throw new ArgumentNullException(nameof(fileList));
            }

            bool filesProcessedSuccessfully = false;

            // Not the greatest here! For illustration only, get a class instance to interrogate app.config AppSettings and use this information to clean the file list data
            try
            {
                IConfigurationHelper configurationHelper = processorLocator.GetProcessor<IConfigurationHelper>();

                List<KeyValuePair<string, string>> appSettings = GetAppSettingsForFileProcessing(configurationHelper);
                CopyAndDeleteFilesBasedOnAppSettings(fileList, appSettings);

                // If we get here then we're successful (by definition that the code didn't error only, of course!)
                filesProcessedSuccessfully = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return filesProcessedSuccessfully;
        }

        #endregion Public Methods

        #region Private Static Helper Methods

        /// <summary>
        /// Private static helper method that uses the provided IConfigurationHelper to 
        /// retrieve AppSettings as a KeyValuePair list (essentially just for convenience).      
        /// /// </summary>
        /// <param name="configurationHelper">The IConfigurationHelper supporting class to retrieve settings based on.</param>
        /// <returns>A list of type KeyValuePair containing the various settings.</returns>
        private static List<KeyValuePair<string, string>> GetAppSettingsForFileProcessing(IConfigurationHelper configurationHelper)
        {
            // Prepare a KeyValuePair list for storing the settings in a more convenient format
            List<KeyValuePair<string, string>> appSettings = new List<KeyValuePair<string, string>>();

            // Using a little linq, get every AppSetting key and value and add it to the appSettings list (ignoring the DesktopAppSettingKey, we don't need this for file processing, so pretty much hard coded for purpose :o) )
            configurationHelper.GetAllConfigurationSettings().AllKeys.Where(appSettingKey => !appSettingKey.Equals(Application.DesktopAppSettingKey, StringComparison.InvariantCultureIgnoreCase)).ToList().ForEach(appSettingKey =>
            {
                appSettings.Add(new KeyValuePair<string, string>(appSettingKey, configurationHelper.GetConfigurationSetting(appSettingKey)));
            });

            // Return the results to the caller
            return appSettings;
        }

        /// <summary>
        /// Private static helper method that consumes a file list and 'settings' to perform
        /// a copy and delete process on each file.
        /// </summary>
        /// <param name="fileList">The files to operate on.</param>
        /// <param name="appSettings">The settings to apply to the files regarding copy and delete processing.</param>
        private static void CopyAndDeleteFilesBasedOnAppSettings(List<string> fileList, List<KeyValuePair<string, string>> appSettings)
        {
            // Loop through each file to process individually (just for illustration)
            string copyLocation = null, fileNameOnly = null;
            fileList.ForEach(file =>
            {
                // Retrieve the file name (only) associated with the path, and log to the console
                fileNameOnly = Path.GetFileName(file);
                Console.WriteLine("Attempting to clean: {0}", fileNameOnly);

                // Retrieve the copy location for this particular file extension, if one is set (again, probably better ways to do this, illustration only)
                copyLocation = appSettings.FirstOrDefault(item => item.Key.Equals(Path.GetExtension(file).Remove(0, 1), StringComparison.InvariantCultureIgnoreCase)).Value;

                // If we have a location to copy to then attempt to perform the copy (then delete the file afterwards from its original location). Failure will halt the process
                if (!string.IsNullOrWhiteSpace(copyLocation))
                {
                    File.Copy(file, Path.Combine(copyLocation, fileNameOnly));
                    File.Delete(file);
                }
            });
        }

        #endregion Private Static Helper Methods
    }
}

Lastly, here is the (very, very simple as it turns out!) wrapper for our DI Container, the ProcessorLocator (implementing IProcessorLocator).

using Autofac;
using DesktopCleaner.Helpers;
using DesktopCleaner.Interfaces;

namespace DesktopCleaner.Locators
{
    /// <summary>
    /// Public class that represents a 'Processor Locator', which
    /// just obtains concrete class based on the DI Container in the Program
    /// class (held statically in the DesktopCleaner.Helpers.Application class, which
    /// is set up when this application is started).
    /// </summary>
    public class ProcessorLocator : IProcessorLocator
    {
        #region Public Expression Bodied Methods

        /// <summary>
        /// Based on T provide a concrete class implementation
        /// (that matches the interface in the DI Container).
        /// </summary>
        /// <typeparam name="T">The interface to get a concrete type based on.</typeparam>
        /// <returns>An instance of the concrete class, as mapped.</returns>
        public T GetProcessor<T>() => Application.Container.Resolve<T>();

        #endregion Public Expression Bodied Methods
    }
}

Just for kicks! For anyone wondering what is found in the app.config, here it is for reference:

<!--App Setting Configuration example (within the app.config)-->
<appSettings>
  <add key="DesktopPath" value="C:\Users\fakeuser\Desktop\Imaginary_Desktop"/>
  <add key="jpg" value="C:\Users\fakeuser\Desktop\Imaginary_Desktop\jpeg_folder"/>
  <add key="url" value="C:\Users\fakeuser\Desktop\Imaginary_Desktop\url_folder"/>
  <add key="txt" value="C:\Users\fakeuser\Desktop\Imaginary_Desktop\txt_folder"/>
  <add key="xlsx" value="C:\Users\fakeuser\Desktop\Imaginary_Desktop\xslx_folder"/>      
</appSettings>

Another reference piece just to finish up before we inspect the actual output; a class diagram for the application as it stands (pretty flat and easy to understand):

Desktop Cleaner class diagram showing application structure.

Desktop Cleaner Class Diagram.

So, what do you get when you run this application? The next screenshot should hopefully give a good indication as to what is going on ‘under the hood’.

Here’s the final output, with the most interesting portion of output being in the first section, showing some details about the objects retrieved from the DI Container (using the ProcessorLocator class). This shows that IFileHelper instances (FileHelper in this case) are retrieved as new instances, whereby the IConfigurationHelper instances are single instances as expected (as per the DI Container configuration):

Console output from the Desktop Cleaner application.

Desktop Cleaner Report.

We now have a rough sample of loosely coupled code without concrete implementations embedded. Let’s have a look at the implications for unit testing.

DI and Unit Testing (Moq)

Does this methodology actually help during a basic unit testing scenario? I’ll be using Moq to find out:

Autofac.Extras.Moq NuGet Gallery Reference

In this example, we (after doing a little bit of setting up) utilise the AutoMock.GetLoose (get automatic mocks using loose mocking behaviour) method to retrieve a type to generate our ‘systems under test’ (i.e. other classes). The coolest thing here is that, as demonstrated by the FileHelperProcessFilesTest method, is the injection of the testMoqConfigurationHelper (which is retrieved when the type under test utilises an IProcessLocator to retrieve an IConfigurationHelper supporting object). This way, we are able to ‘rig’ certain parts of an implementation to focus down our unit tests to only specific areas of business logic, certainly very neat indeed. I’ve included all of the implementation code for reference (all commented to add clarity where required).

More details can be found here for those who want to delve a little deeper in Moq:

Moq Documentation

using Autofac.Extras.Moq;
using DesktopCleaner.Implementations;
using DesktopCleaner.Interfaces;
using DesktopCleaner.UnitTests.Helpers;
using DesktopCleaner.UnitTests.MoqObject;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DesktopCleaner.UnitTests
{
    /// <summary>
    /// Public class that holds all of the Unit Test logic to
    /// run Moq tests against the DesktopCleaner application.
    /// </summary>
    [TestClass]
    public class DesktopCleanerTests
    {
        #region Private Static Data Fields (For Unit Tests)

        /// <summary>
        /// Private data fields that represent paths for directories
        /// to used during these unit tests (purely for demonstration).
        /// </summary>
        private static string testDesktopPath = Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder),
            testTxtFilesPath = Path.Combine(testDesktopPath, SharedTestValues.TestTxtFilesFolder),
            testSqlFilesPath = Path.Combine(testDesktopPath, SharedTestValues.TestSqlFilesFolder);

        #endregion Private Static Data Fields (For Unit Tests)

        #region Test Class Initialisation Logic

        /// <summary>
        /// Public method that sets up the required resources for all
        /// of the Unit Tests featured in this class. NOTE: There is a requirement 
        /// for all of the tests to run (you wouldn't want to introduce a 'link' between all
        /// of your tests in production, but as I'm doing a demo this is permissible for now).
        /// </summary>
        /// <param name="context">The TestContext object for this class.</param>
        [ClassInitialize]
        public static void ConfigureTestResources(TestContext context)
        {
            // Create a Test Desktop folder and a TXT/SQL folder as sub-directories (ready to receive content in the tests below)
            Directory.CreateDirectory(testDesktopPath);
            Directory.CreateDirectory(testTxtFilesPath);
            Directory.CreateDirectory(testSqlFilesPath);

            // Add four tests files, two SQL files and two standard TXT file, into the root directory (for 'cleaning' during the unit tests)
            File.Create(Path.Combine(testDesktopPath, SharedTestValues.TestTxtFileNameOne)).Close();
            File.Create(Path.Combine(testDesktopPath, SharedTestValues.TestTxtFileNameTwo)).Close();
            File.Create(Path.Combine(testDesktopPath, SharedTestValues.TestSqlFileNameOne)).Close();
            File.Create(Path.Combine(testDesktopPath, SharedTestValues.TestSqlFileNameTwo)).Close();
        }

        #endregion Test Class Initialisation Logic

        #region Public Static Test Methods

        /// <summary>
        /// Public test method that runs an implementation test against
        /// a FileHelper class and the GetFilesForPathAsList method.
        /// </summary>
        [TestMethod]
        public void FileHelperGetFilesForPathAsListTest()
        {
            using (AutoMock mock = AutoMock.GetLoose())
            {
                // Arrange (i.e. configure the mock)
                FileHelper sut = mock.Create<FileHelper>();

                // Act
                List<string> directoryList = sut.GetFilesForPathAsList(new MoqConfigurationHelper().GetConfigurationSetting(SharedTestValues.DesktopTestAppSettingKey));

                // Assert
                Assert.AreEqual(4, directoryList.Count);
            }
        }

        /// <summary>
        /// Public test method that runs an implementation tests against
        /// a FileHelper class and the ProcessFiles method primarily (ensuring that 
        /// the FileHelper receives a 'mock' version of an IConfigurationHelper for 
        /// testing purposes, which returns a predefined configuration to test against).
        /// </summary>
        [TestMethod]
        public void FileHelperProcessFilesTest()
        {
            using (AutoMock mock = AutoMock.GetLoose())
            {
                // Arrange (i.e. configure the mock)
                MoqConfigurationHelper testMoqConfigurationHelper = new MoqConfigurationHelper();

                // This is the interesting bit - Pass the MoqConfigurationHelper as our implementation of IConfigurationHelper. This turns up in the constructor of our FileHelper (for use in the Unit Test)
                mock.Mock<IProcessorLocator>().Setup(loc => loc.GetProcessor<IConfigurationHelper>()).Returns(testMoqConfigurationHelper);
                FileHelper sut = mock.Create<FileHelper>();

                // Act
                List<string> directoryList = sut.GetFilesForPathAsList(testMoqConfigurationHelper.GetConfigurationSetting(SharedTestValues.DesktopTestAppSettingKey));

                // Assert
                Assert.IsTrue(sut.ProcessFiles(directoryList));
                Assert.IsFalse(Directory.GetFiles(testTxtFilesPath).Any(file => !Path.GetExtension(file).Equals(".txt")));
                Assert.IsFalse(Directory.GetFiles(testSqlFilesPath).Any(file => !Path.GetExtension(file).Equals(".sql")));
            }
        }

        #endregion Public Static Test Methods

        #region Test Class Cleanup Logic

        /// <summary>
        ///  
        /// </summary>
        [ClassCleanup]
        public static void CleanupTestResources()
        {
            // Remove traces of test files, for our next run (as this is all plonked in the debug/bin folder, not what you'd want for a genuine test setup most likely)
            Directory.GetFiles(testTxtFilesPath).ToList().ForEach
                (
                    file => 
                    {
                        File.Delete(file);
                    }
                );

            Directory.GetFiles(testSqlFilesPath).ToList().ForEach
                (
                    file => 
                    {
                        File.Delete(file);
                    }
                );

            Directory.GetFiles(testDesktopPath).ToList().ForEach
                (
                    file => 
                    {
                        File.Delete(file);
                    }
                );

            // Remove any test directories created for any run Unit Tests
            Directory.Delete(Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder, SharedTestValues.TestTxtFilesFolder));
            Directory.Delete(Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder, SharedTestValues.TestSqlFilesFolder));
            Directory.Delete(Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder));
        }

        #endregion Test Class Cleanup Logic
    }
}
using System;
using System.IO;

namespace DesktopCleaner.UnitTests.Helpers
{
    /// <summary>
    /// Public static class that holds all of the 
    /// </summary>
    public static class SharedTestValues
    {
        #region Private Static Data Fields

        /// <summary>
        /// Private static data field that (poorly named really) gets access
        /// to the current directory for this application (for our purposes, during debugging, this
        /// will be the bin/debug folder, for demonstration only).
        /// </summary>
        private static Lazy<string> debugPath = new Lazy<string>(() => Directory.GetCurrentDirectory());

        #endregion Private Static Data Fields

        #region Public Constants

        /// <summary>
        /// Public constant that denotes the desktop path
        /// mock up AppSetting key (not actually real, faked
        /// by our MoqConfigurationHelper).
        /// </summary>
        public const string DesktopTestAppSettingKey = "DesktopPath";

        /// <summary>
        /// Public constant that denotes the desktop folder name 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestDesktopFolder = "Test_Desktop";

        /// <summary>
        /// Public constant that denotes the text file folder name 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestTxtFilesFolder = "Txt_Files";

        /// <summary>
        /// Public constant that denotes the sql file folder name 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestSqlFilesFolder = "Sql_Files";

        /// <summary>
        /// Public constant that denotes the name of the first, test sql file 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestSqlFileNameOne = "Test_Sql_File_One.sql";

        /// <summary>
        /// Public constant that denotes the name of the second, test sql file 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestSqlFileNameTwo = "Test_Sql_File_Two.sql";

        /// <summary>
        /// Public constant that denotes the name of the first, test text file 
        /// to use during Unit Testing.
        /// </summary>
        public const string TestTxtFileNameOne = "Test_Txt_File_One.txt";

        /// <summary>
        /// Public constant that denotes the name of the second, test text file 
        /// to use during Unit Testing. 
        /// </summary>
        public const string TestTxtFileNameTwo = "Test_Txt_File_Two.txt";

        #endregion Public Constants

        #region Public Static Properties

        /// <summary>
        /// Gets access (static) to the lazy debugPath.value.
        /// </summary>
        public static string DebugPath
        {
            get
            {
                return debugPath.Value;
            }
        }

        #endregion Public Static Properties
    }
}
using DesktopCleaner.Interfaces;
using DesktopCleaner.UnitTests.Helpers;
using System.Collections.Specialized;
using System.IO;
using System.Linq;

namespace DesktopCleaner.UnitTests.MoqObject
{
    /// <summary>
    /// MoqConfigurationHelper class to provide a specific implementation of an
    /// IConfigurationHelper just for Unit Testing (not necessarily how best to structure
    /// a class, just for illustration purposes only).
    /// </summary>
    public class MoqConfigurationHelper : IConfigurationHelper
    {
        #region Private Static Data Fields

        /// <summary>
        /// Private static data field that represents a mock
        /// set of Application Settings for use during Unit Testing.
        /// </summary>
        private static NameValueCollection testAppSettingsCollection = null;

        #endregion Private Static Data Fields

        #region Constructor

        /// <summary>
        /// Initialises a new instance of a MoqConfigurationHelper.
        /// </summary>
        public MoqConfigurationHelper()
        {
            // THIS COULD, OF COURSE, BE STORED IN AN APP.CONFIG ALSO AS PART OF THIS PROJECT, BUT I WANT TO DEMONSTRATE A FULL MOCK UP HERE AND FANCY DOING A BIT MORE HARD WORK!

            // Set testAppSetingsCollection to be a new NameValueCollection
            testAppSettingsCollection = new NameValueCollection();

            // Create three, mock 'AppSettings' denoting a desktop, sql and text files path (to be used during Unit Tests)
            testAppSettingsCollection.Add(SharedTestValues.DesktopTestAppSettingKey, Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder));
            testAppSettingsCollection.Add("Sql", Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder, SharedTestValues.TestSqlFilesFolder));
            testAppSettingsCollection.Add("Txt", Path.Combine(SharedTestValues.DebugPath, SharedTestValues.TestDesktopFolder, SharedTestValues.TestTxtFilesFolder));
        }

        #endregion Constructor

        #region Public Expression Bodied Methods

        /// <summary>
        /// Public method that returns all 'AppSettings'
        /// (mock only) to the caller.
        /// </summary>
        /// <returns></returns>
        public NameValueCollection GetAllConfigurationSettings() => testAppSettingsCollection;

        /// <summary>
        /// Public method that returns a specified AppSetting
        /// to the caller based on key (mock only).
        /// </summary>
        /// <param name="key">The unique key for the value to be retrieved.</param>
        /// <returns>The value corresponding to the unique key.</returns>
        public string GetConfigurationSetting(string key) => testAppSettingsCollection.GetValues(key).FirstOrDefault();

        #endregion Public Expression Bodied Methods
    }
}

Being a stickler for providing full details, here is the class diagram for the Unit Test project:

Desktop Cleaner unit test project class diagram illustrating structure.

Desktop Cleaner Unit Test Project Class Diagram.

As a final thought, here’s a little bit of proof captured at runtime showing the different concrete implementations retrieved when hitting a breakpoint during debug of the application running in and out of a unit testing scenario:

Illustration showing the IConfigurationHelper object type during debug.

IConfigurationHelper Object Type During Debug.

Illustration showing the IConfigurationHelper object type during unit testing.

IConfigurationHelper Object Type During Unit Testing.

Since generating content for this post I’ve had more thoughts and ideas surrounding DI in general, something that seems to make a follow-up post a worthy thing to pursue! I’d like to flesh these examples out at the very least, so watch this space for more on this subject.

Thanks again all, until the next time…

A Few Hours With….F#

What can I learn about F# in the time it takes to drink a coffee, eat some biscuits and listen to a few tracks on Spotify; let’s find out. This post was supposed to be entitled “Thirty Minutes With…F#” but I ended up getting far too engrossed and a couple of hours skipped by (followed by more coffee and biscuits)!

This is something that I’ve been meaning to cover and is a topic that has come up among friends and colleagues; there’s certainly an interest in this language so I’ll pop the hood and have a little look.

For starters, although it’s a few years old now, I found this discussion on the topic interesting:

F# with Richard Minerich & Phillip-Trelford (Hanselminutes.com)

As a basis for this little peek, I’ll be using http://www.tryfsharp.org, instead of any of the integrated Visual Studio features (which do exist, so I may do a follow up after this taster).

EXTRA NOTE: In the interim since starting this post, I actually attended the Future Decoded 2015 event where there was a fantastic F# breakout session by Don Syme; this has very much peaked my interest further.

What is F#?

Prior to writing this post I’d pegged F# as a scripting language geared to solving complex mathematical problems in a clean manner; hence its inherent link with the financial market and software created to function in this particular sector. However, based on the Hanselminutes.com podcast and the content presented on tryfsharp.org, it seems as if I may possibly be underselling it. We find that F# is now pushing itself as a fully-featured and rich alternative (or at least considering itself as a powerful language to commonly interoperate with, not just for mathematical problems) to existing object-orientated languages such as C# and Java.

So, the take away points:

  • Strongly-typed, functional-first programming language.
  • Open source.
  • Cross platform.
  • Expressive and concise (i.e. terse).
  • Whitespace Sensitive.

Setup

When using the tryfsharp.org site, the first hurdle that you’ll have to jump is compatibility issues with the Silverlight plugin used to drive the web editor. During my testing I had issues in Chrome and Edge, as outlined below:

Chrome Unsupported.

Chrome Unsupported.

I came up trumps in FireFox, IE 11 and Opera (for now):

Opera Supported!

Opera Supported!

I settled on using FireFox and didn’t come across any issues whilst going through the tutorials presented in the getting started section. Perhaps the browser compatibility is something that will get addressed or is something that I just need to read up on. Silverlight is still slowly coughing and spluttering its way to an eventual demise either way!

Getting Started in F# – Section by Section

I’m going to give a very basic and brief rundown of the content presented in the first few sections provided on the site. This isn’t an exhaustive list of all of the content presented or a full representation of the information available; this just represents my first ‘comb through’.

Bindings, Values and REPLs

To begin with, we are presented with the REPL (Read Evaluate Print Loop), which executes the code within the editor. The REPL provides an on-going output so you can build up programs incrementally (i.e. keep a track of basic mathematical output for instance). You can opt to execute code in its entirety, in blocks or line by line by highlighting statements and using the run command (or using Ctrl+Enter). One gotcha here, the equivalent command in Visual Studio called F# Interactive, which allows you to execute scripts line by line or in blocks, requires you to use Alt+Enter. I’ve seen resources that state this could cross over with some Re-Sharper keyboard shortcuts; this is one to look out for and adjust key bindings as required.

Binding names to values (declaring and setting variables in a traditional sense) is achieved using the let keyword:

//Declare and set a variable called bookCount to 10
let bookCount = 10

In a variation to C#, let bindings are immutable in F#, meaning that out of the gate the following with cause errors and behaviour you may not expect if you’re not on your guard:

//The following code results in "Book Count: 10" - bookCount does not allow mutation after the original assignment (binding)
let bookCount = 10 
bookCount = 11 
printfn "Book Count: %d" bookCount          //printfn is a utility function (in FSharp.Core.dll) that allows printing to the output window (various formats are allowed for variables that you want to inject into the resultant string)

//Duplicate definition of value 'valueOne' error thrown
let valueOne = "Value One"
let valueOne = "Value Two"

You’ll notice that I’ve thrown in a reference to the printfn function; a real staple for providing formatted output as and when needed. Further help can be found here:

Core.Printf Module

So what if you need to actually ‘mutate’ a value after its original assignment? Thankfully, this is possible via the mutable keyword, as illustrated in this simple example of a looping construct:

//Declare a particular variable using the mutable keyword so the value can change after assignment
let mutable countVar = 1
 
for item in itemArray do
    //Perform some kind of function (using the countVar value in this case)...
    countVar <- countVar + 1 //Increment countVar

As a side note, you can see that ‘<-' is used for assignment purposes (as opposed to the usual '=' operator).

Also, if executing statements singularly, it is possible to use a technique called shadowing to overwrite an initial binding as in this example:

//Executing this line...
let shadowed = "first value"

//Then this line, separately...
let shadowed = "second value"

//Prints "value = second value"
printfn "value = %s" shadowed

It’s important to note that the second statement here (let shadowed = “second value”) creates a new binding that shadows, or masks, the original.

F# is very much statically typed, as this code illustrates (types are inferred correctly in the output window on inspection):

let intTest = 10
let floatTest = 10.55
let stringTest = "Twenty Two"

A key plus of F# (as touted anyway) is that it goes to much greater lengths to perform type inference, to a larger degree than most statically/strongly typed languages. It’s looking to walk the very fine line between the enhanced readability of a dynamic language and the more robust nature of a statically typed language. My early impressions suggest that F# is doing a good job at finding a balance.

Functions

Functions in F#, in-line with traditional data values, are also created using the let keyword to bind a name to a function. You’ll notice that in a very simple function definition, such as in the next example, the specifying of types in relation to parameters isn’t strictly required. Based on how I’ve called the function F# infers the type of x and y to be integer:

let calculateRectPerimeter x y =
    ((x * 2) + (y * 2))

calculateRectPerimeter 4 6

As another example, this call to a function named multiply was defined using float values for both arguments; F# infers the types of these arguments correctly:

let multiply x y =
    x * y 

multiply 4.5, 6.2

A few gotchas crept into the fold here, namely surrounding mixing of types (integers and floats in my case) which, as opposed to C#, is not allowed in F# without explicit casting. Here’s a useful troubleshooting guide for anyone interested in doing some further reading:

F# Troubleshooting

So far you’ll have observed that the scaffolding required to define and use a simple function is very lightweight. No curly braces, brackets (until you start to enforce types as specified below) or comma-separation of arguments is required at this stage (which is quite nice I have to admit).

This leads nicely onto the topic of Type Annotations. In a nutshell, this simply means to define types in a function signature when the function operates on an input parameter in a type specific manner. This example is pulled directly from the learning resources provided online:

let toHackerTalk (phrase:string) =
    phrase.Replace('t', '7').Replace('o', '0')

toHackerTalk "terry ono"

F#, in wording stripped from the site, treats functions as First Class Citizens. This means, due to their nature of being bound to a name using the let keyword, you can create helpers functions within functions and use functions (as with C# methods) as arguments to other functions (termed Higher Order Functions):

//1) FUNCTIONS WITHIN FUNCTIONS

//Monthly pay is 4x weekly salary (addBonus doubles this value, if only!)
let calculateMonthlyPay x =    
    //Function defined within calculateMonthlyPay as an additional helper (called directly by this function)
    let addBonus x =
        x * 2

    addBonus(x * 4)

//Call calculateMonthlyPay ((250 * 4) * 2) = 2000    
let payResult = calculateMonthlyPay 250

//2) FUNCTIONS AS ARGUMENTS

//First, we define a simple test function that returns a fixed value
let magicNumber number =
    number 7

//Next, we create a function to test an input    
let testMagicNumber number =
    if number = 7 then
        "It's the magic number!"
    else
        "It's not the magic number..."

//Call testMagicNumber with the magicNumber function as an argument        
magicNumber testMagicNumber

This seemed very intuitive apart from, being completely honest, the nature in which you provide functions as arguments; these function arguments are defined before the function you want to call. A definite switch up from C# and something that made me stare at the screen for a couple of minutes :-?. Also, note the use of the ‘=’ operator for use in the comparison here, this doesn’t mean an assignment is occurring.

The last thing presented in this section is Lambda Functions, the syntax for which seems tight and easy to interpret for someone with a C# background:

//Lambdas (Anonymous Function) in action
let divide = (fun x y -> x / y)
divide 8 2

//testFunction returns 16
let testFunction test =
    test 16

//Using testFunction as an argument for an anonymous function (x will be 16). Divide (using our previous function) 32 by x, if the result is 2 or greater return true, else false
testFunction (fun x -> divide 32 x >= 2)

Chaining Functions and the Forward Pipe Operator

Hopefully anyone reading this hasn’t dozed off, head hitting the keyboard, etc so apologies in advance; this has turned into a bit of a ‘beast’! Thankfully, this particular section will be a little shorter.

For starters, lists in F# are handled in an incredibly succinct manner. You can create lists of defined values or a list based on a value range very easily as follows:

//A list of ages (note the semi-colon separation of values)
let ages = [24; 31; 32; 50]

//A list of numbers (0 through to 250 using the '..' syntax)
let aLotOfNumbers = [0..250]

//Just to prove it...
printfn "aLotOfNumbers has a length of: %d" (aLotOfNumbers.Length - 1)

Here, the lists are inferred to be of type int based on the contained values. I can see how this could be an incredibly useful way to do some load testing or as part of a larger unit testing strategy.

The List type provides functions for operating on lists, whether this be performing calculations, aggregation, filtering or projecting whole new lists. I worked with a few additional examples in my ‘culmination experiment’, but here I’ll focus on List.map and List.filter. Firstly, List.map is used to project a new data set based on the mapping function supplied. List.filter uses a predicate, which only provides results that return true for the given predicate. If using more than one ‘List’ function, as denoted by the training resources, you can use the Forward Pipe Operator to improve readability significantly:

//Bind a list using the let keyword (numbers 0 to 100)
let firstHundred = [0..100]

//Project a new list that contains numbers in the firstHundred list doubled
let doubledValues = List.map (fun x -> x * 2) firstHundred

//Filter values from 0 to 100 to even values only. Project a new list that contains these values doubled
firstHundred
List.map (fun x -> x * 2)
    (List.filter (fun x -> x % 2 = 0) firstHundred)
    
//Not using the let keyword this time, specify a starting list containing numbers 0 to 50 (Total = 1300) - Using Forward Pipe Operator
[0..50]
|> List.filter (fun x -> x % 2 = 0)     //Filter to only even numbers
|> List.map (fun x -> x * 2)            //Double the remaining numbers after filtering
|> List.sum                             //Sum the total values remaining (after filtering/doubling)

There’s a great stock data based example on the site listed at this point which I’ll leave for you to discover on your own 😉 (taking into account the size of this post so far!); needless to say it encapsulates the ideas covered here and served as a grounding for my forays in building the larger program below.

Data Structures

I haven’t yet delved into the F# object-orientated type system, but I did have just enough time to look over the more simplistic and lightweight options.

Record Types allow for the basic grouping together of data. The tutorial uses the example of a book, so I’ll use the source material directly to serve as an example:

//Book Record Type (outline for a 'Book' which defines fields and underlying types)
type Book = 
  { Name: string;
    AuthorName: string;
    Rating: int;
    ISBN: string }

//Type of Book inferred here based on the fields (properties) defined here matching the Book Record Type
let expertFSharp = 
  { Name = "Expert F#";
    AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino";
    Rating = 5;
    ISBN = "1590598504" }

//Use the books Rating to provide output    
printfn "I give this book %d stars out of 5!" 
    expertFSharp.Rating

Record bindings are immutable also, so altering a books ‘Name’ for example will error. F# provides syntax for creating a new Record Type with an updated field value:

//Record Type bindings are immutable also; this throws an error
expertFSharp.AuthorName <- "Chris Marinos"    

//Create a new Book type, based on the existing book, with a new 'Name'
let partDeux = { expertFSharp with Name = "Expert F# 2.0" }

The type inference that occurs here can cause issues if another Record Type contains the same field names but with an opposing type. Thankfully, explicitly stating which type you want a bound value to relate to is as easy as specifying a prefix label on one of the field assignments (you only need to do one to cover the entire type):

type Book = 
  { Name: string;
    AuthorName: string;
    Rating: int;
    ISBN: string }

type VHS =
  { Name: string;
    AuthorName: string;
    Rating: string;                                                 // Videos use a different rating system.
    ISBN: string }

//Binding fixed here by using Book.Rating
let expertFSharp = 
  { Name = "Expert F#";
    AuthorName = "Don Syme, Adam Granicz, Antonio Cisternino";
    Book.Rating = 5;                                                //Using the explicit label 'Book' here means this in its entirety is now treated as a Book, neat trick            
    ISBN = "1590598504" }

In the scenario whereby a particular field may or may not contain a value (the classic nullable scenario), F# defines the option, Some and None keywords. I’d love to read up on this further; the approach, to me at least, seems to be to create a safety blanket that doesn’t allow for the pesky null reference exception. When calling traditional .Net code this will still be an issue of course; but within the realm of F# the idea of making the developer accountable for this state management (and not just letting something ‘be null’) really intrigues me – Note to self for further reading! In addition, you are able to use a Pattern Matching check using the match/with construct. Here’s a complete example to whet the whistle:

//All people have a Name and Age, but not all people have a Book Club Membership Number
type Person = 
    { Name: string;
      Age: int;
      BookClubMemNo: int option }   //option denotes that data may not exist

//Define Steve - He has no Book Club Membership (None keyword used represent this)   
let steve = 
    { Name = "Steve Smith";
      Age = 32;
      BookClubMemNo = None }
      
//Define Jane - She loves her books, therefore she has a Book Club Membership (Some 'value' used to represent this)
let jane = 
    { Name = "Jane Smith";
      Age = 29;
      BookClubMemNo = Some 125485422 } 
      
//Define a function to 'Pattern Match' - Does the BookClubMemNo of a person have a value?
let bookClubMemDetails person =
    match person.BookClubMemNo with
        | Some memNo -> printfn "%s has a Book Club Membership Number of %d" person.Name memNo
        | None -> printfn "%s has no Book Club Membership" person.Name

//Test our function
bookClubMemDetails steve
bookClubMemDetails jane
Pattern Matching In Action.

Pattern Matching In Action.

The last thing I’d like to discuss, and is the final item on the learning resources checklist for getting started, is Discriminated Unions. These look and feel, on the face of it, like something akin to a C# enum type. You can use the same Pattern Match construct (which is very much an equivalent, in a basic sense, to a ‘case’ statement) as above to operate on a Discriminated Union. As a final note, and you’ll see this in the code sample below, Discriminated Union members can be ‘bundled’ together to create more complex scenarios (i.e. defining a sponsor type that’s associated with large football clubs sponsor).

Melting Pot Example

So, as a culmination to what I’d managed to glean in the first hour and a bit, I came up with a little fictional, football data interrogation sample (because…urm, I’m geeking out!). Here’s the final code sample and full comments to boot:

//Test Scenario
//------------------------
//Calculate football team point totals (only for teams whereby they have 10 or more wins) and provide the name of the team who is winning the league

//Defines a teams strip colour options
type StripColour =
| Red
| Yellow
| Green
| Blue

//Defines some secondary information about teams sponsors and sponsor sizes
type LargeSponsorSubTypes =
| Finance
| Oil
| Military

type SponsorSizeType = 
| Large of LargeSponsorSubTypes     //Large sponsors have a defined sub-type as above
| Medium
| Small

//Defines the structure of a football team data item
type FootballTeam =
    { Name: string;
      Wins: int;
      Draws: int; 
      MainKitColour: StripColour;
      SponsorSize: SponsorSizeType option
      Sponsor: string option; }

//Defines a data set surrounding football teams win/draw total (data items type inferred based on 'property' names)
let footballTeamData = 
    [
        { Name = "Roaring Tigers FC"; Wins = 8; Draws = 10; MainKitColour = Red; SponsorSize = Some Small; Sponsor = Some "Tiger Juice" };
        { Name = "Squeaking Mice Town"; Wins = 13; Draws = 6; MainKitColour = Green; SponsorSize = None; Sponsor = None };
        { Name = "Elephant City FC"; Wins = 12; Draws = 3; MainKitColour = Yellow; SponsorSize = Some Medium; Sponsor = Some "Elephant House Movers" };
        { Name = "Lazy Leopard Wanderers"; Wins = 3; Draws = 6; MainKitColour = Blue; SponsorSize = None; Sponsor = None };
        { Name = "Jolly Pirates FC"; Wins = 16; Draws = 6; MainKitColour = Green; SponsorSize = Some Small; Sponsor = Some "Pirate Clothing"; };
        { Name = "Norwich City FC"; Wins = 9; Draws = 9; MainKitColour = Yellow; SponsorSize = Some (Large Finance); Sponsor = Some "Aviva"; };
    ]

//Helper function to calculate a teams points based on wins and draws
let calculatePoints wins draws =
    ((wins * 3) + draws)
 
//1) Who is leading the league as it stands (based on total points) - In my weird and wonderful world you must have at least 10 wins to be included in the calculation
printfn "\r\nCurrent League Leader\r\n==============================" 
   
footballTeamData 
|> List.filter(fun team -> team.Wins >= 10)                                                                                     //10 win minimum
|> List.maxBy(fun team -> calculatePoints team.Wins team.Draws)                                                                 //Get the max by the amount of points the team has got                    
|> (fun team -> printfn "%s is leading the league with %d points.\r\n" team.Name (calculatePoints team.Wins team.Draws))        //Print out the teams name and points total

//DO SOME OTHER PROCESSING FOR FUN
//2) Print out a league table (all teams included - Order by point totals)
printfn "Current Standings and Team Information\r\n=============================================" 

let orderedTeamData = 
    footballTeamData
    |> List.sortBy(fun team -> -calculatePoints team.Wins team.Draws)       //Seems to be a sortByDescending in F# 4.0, the negative hack fits purpose here for the time being
    
let mutable teamPlace = 1 
for team in orderedTeamData do
    printfn "%s is at position %d in the league with %d points and a %A kit colour." team.Name teamPlace (calculatePoints team.Wins team.Draws) team.MainKitColour
    teamPlace <- teamPlace + 1
    
//3) Process team sponsors and types and do some pattern matching to finish up
printfn "\r\nTeam Sponsor Information\r\n=============================================" 

//Define a helper function to process each teams sponsor information
let handleTeamSponsorInfo team =
    match team.SponsorSize with
    //Team has a sponsor size so keep interrogating data (we have a sponsor name)
    | Some sponsorSize -> match sponsorSize with
                            //Handle each sponsor size separately (large sponsors have a sub-type so demonstrate how these could be handled differently)
                            | Large largeSponsorSubType -> match largeSponsorSubType with
                                                            | Finance -> printfn "%s has a Large-sized Sponsor (name: '%A') with a Finance subtype. As this is Finance based do blah blah..." team.Name team.Sponsor
                                                            | Oil -> printfn "%s has a Large-sized Sponsor (name: '%A') with an Oil subtype. As this is Oil based do blah blah..." team.Name team.Sponsor
                                                            | Military -> printfn "%s has a Large-sized Sponsor (name: '%A') with a Military subtype. As this is Military based do blah blah..." team.Name team.Sponsor
                            | Medium -> printfn "%s has a Medium-sized Sponsor (name: '%A')." team.Name team.Sponsor
                            | Small -> printfn "%s has a Small-sized Sponsor (name: '%A')." team.Name team.Sponsor
    //No sponsor size (hence, no sponsor type as defined by the data I've rigged for this example)
    | None -> printfn "%s has no sponsor." team.Name
    
//Call the function to inspect team sponsor info (for each and every team in the original, un-ordered data set)
for team in footballTeamData do
    handleTeamSponsorInfo team
    
//TO IMPROVE 
//-> Include a team 'Points' property and calculate this up front (to reduce calls to calculatePoints)
//-> Alter formatting options to remove the 'Some' part of the output within the handleTeamSponsorInfo function

Type Providers

I had another half hour to spare, and I desperately wanted to (following the Future Decoded demonstrations) have a very quick play with F# Type Providers. This example doesn’t go into charting, which I’ll reserve as a cherry-on-top topic for another day, but covers an example of scraping a web page for data using the HtmlProvider. In the example below I’m pulling data on browser usage from the w3schools website (directly from a table on the browser_stats.asp page of the site).

The basic premise is that you provide a sample HTML snippet to define a ‘type’; this essentially gives you strongly typed members to run with in order to rip information out of a web page on-demand. You’ll notice that this approach is indeed sensitive to restructuring changes made at the website page level, which is to be expected, but it’s an interesting premise for interrogating online data sources in real-time.

Here’s the full code snippet, produced in Visual Studio this time around with a NuGet package installed for FSharp.Data:

//Bring the FSharp.Data namespace into scope
open FSharp.Data

//Define a type to house browser stats information (based on an example file)
type BrowserStats = HtmlProvider<"DataFormat.htm">

[<EntryPoint>]
let main argv = 

    //Retrieve the latest, 2015, browser statistics for w3schools (example file defines a 'outline' so we know how the data is structured - A schema of sorts)
    let browserStatInfo = BrowserStats.Load("http://www.w3schools.com/browsers/browsers_stats.asp").Tables.``Browser Statistics``

    //Write a title to the console
    System.Console.WriteLine("2015 Browser Statistics\r\n=============================\r\n")

    //Write, to the console, stats for each browser (row by row from the relevant html table)
    for row in browserStatInfo.Rows do
        System.Console.WriteLine("{0} -> Chrome: {1}, IE: {2}, FireFox {3}, Safari {4}, Opera {5}", 
            row.``2015``, row.Chrome, row.IE, row.Firefox, row.Safari, row.Opera)

    //Do not close until we have had time to inspect the data
    System.Console.ReadKey() |> ignore

    0 // return an integer exit code

Example output from the console application utilising the above code:

Browser Statistics Console Output.

Browser Statistics Console Output.

In summary, I’ve really enjoyed working with F# (in this initial exploratory sense). I can certainly see enough here to warrant a further deep dive and possibly purchasing a book here or there down the road. I hope you’ve enjoyed reading through. Now, where did I put my semi-colons again, I can’t find them at the end of any statements…

All the best!

Visual Studio 2015 First Impressions – PerfTips

I’ve had a super quick tour of Visual Studio 2015 Community Edition and I have to say I’m pretty impressed as it stands. I’m currently downloading Unity 5 and will be installing the latest toolkits shortly that go hand in hand with this.

In the meantime, I’ve been looking at some of the new debugging performance aids; namely, PerfTips.

Full information can be found here:

Visual Studio PerfTips

In the example screenshot below I have rigged some methods (using the new async syntax in a rough and ready way) to simulate a slight delay in the retrieval of information. I’ve placed breakpoints in the code and you can see that, when hit, a small diagnostic message is shown in the editor detailing the time, in milliseconds, that have elapsed during the previous method call. Very, very nice:

PerfTips In Action

PerfTips In Action

You will also notice that some extra diagnostics, listing the events that have occurred so far and interesting metrics such as memory usage, are being shown in the Diagnostic Tools window on the far right. This is something I’ll have a further dig into; looks interesting on first glance.

The only thing I didn’t like off the bat was the default colour of the PerfTip text itself (which is non-descript when not highlighted, as standard). I have a penchant for the Visual Studio Dark theme so I prefer colours to pop a little more, just personal taste really. Thankfully, this can be easily rectified by navigating to Tools > Options > Environment > Fonts and ‘Colours’ (sorry, I’m British, I can’t help myself!) as shown here:

PerfTips Before Customisation.

PerfTips Before Customisation.

From here, you can adjust the Item foreground value (ensuring that PerfTips is selected from the Show Settings for drop down and that Text is highlighted in the Display items selection box). Of course, you’re also free to set the colour of the PerfTip text when highlighted as well by selecting the Highlighted Text item from the Display Items selection box and adjusting the Item foreground to the desired colour. If the colours on offer don’t float your boat then the usual custom colour picker is present also.

You can fly by this handy, dandy post for more details:

Customise PerfTips

The end result (depending on the colour you pick) is as follows:

PerfTips After Customisation.

PerfTips After Customisation.

I did receive a message stating that the application may need a restart for changes to take hold. In this case, I got away with it and the change kicked in immediately.

Anyway, just a short post for tonight. I will detail any other interesting finds as they crop up.

Until the next time!