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…

Future Decoded 2015 Play-by-play

Hello beautiful people!

It’s a fantastic, gorgeous Saturday morning (it’ll be Monday by the time I hit the publish button, such is the enormity of the post!); the birds are chirping, the sun is shining through the balcony windows (and there is a bloody wasp outside, STILL!!!) and my wife has left me…………to go on a girly weekend (that probably sounded more alarming than intended; hmmm, oh well, it stays!). Whilst she is away fighting the good fight, this gives me the opportunity to go over my thoughts on the recent Future Decoded 2015 event that took place at ExCel in London.

The links to outline this event have been posted before on my blog, but just in case, here are the goods again:

Future Decoded 2015
Future Decoded 2015: Technical Day Highlights

Before we begin, it’s worth pointing out that I attended this event a couple of weeks ago, so apologies if any inaccuracies pop up. I’ll do my best to stick to the facts of what I can remember and specific points that interested me; other commitments ended up preventing me from getting to this particular post sooner. You’ll all let me off, being the super gracious, awesome folks you are, I’m sure :-).

So, FIGHT!!!!!

Sorry, I had a dream about Mortal Kombat last night and upper-cutting people into the pit – What a great stage that was! Ah, the memories….Let’s begin/start/get on with it then.

Morning Key Notes

The morning Key Notes were varied and expansive in nature. I won’t discuss all of them here, only the takeaway points from the talks that struck a chord with me.

1) Scott Guthrie. EVP Cloud and Enterprise, Microsoft (Azure).

I was particularly looking forward to this talk being a keen follower of Scott Guthrie (include Scott Hanselman), and I normally try to catch up with Channel 9 features and Azure Fridays whenever possible (I’ve linked both, although I’m sure most of you, if not all, have come across Channel 9 before or heard of Azure Fridays).

The talk did have primer elements as you would expect, i.e. here’s the Azure Portal and what you can expect to find (in relation to resources, templates you can access for applications, services, Content Distribution Networks (CDN), etc). The next bit really caught me cold, who was expecting a giant image slide of a cow! I certainly wasn’t…

Estrus in Cows

What followed was a full example of real-time data recording and assessment surrounding the monitoring of cows in Asia. I’ve provided a link below that sums up the concept of Estrus (being in heat) nicely enough, but it laymen’s terms it relates to cows ‘being in the mooooooood’ (wife insisted I added that joke). Obviously, a farmers’ ability to accurately detect this, urm, state of being in a cow is an incredibly important factor in the ability to produce calves.

It turns out that a cow tends to move more when in the Estrus state; something that can certainly be measured. So, with pedometers attached to cows to measure steps taken and an Azure based service receiving and providing feedback in real-time, the farmer in question was able to take action to maximise calf production. Further to this, analysis of the data gathered was able to identify trends against how long cows have been in the Estrus state, and the gender of offspring. Crazy stuff, but all very interesting. Feel free to read further to your hearts content:

Cow Estrus Detection

The Internet of Things (IoT) was briefly touched on and another brief, live coding example ensued.

Scott produced a small, bog-standard heat sensor (apparently, just a few pounds, I was impressed he didn’t say dollars!) and proceeded to demonstrate a basic WinForms application passing a JSON payload to Azure in real-time (measurements taken a few times a second). This strikes me as exciting territory, and I have friends who do develop applications working in tandem with sensors already, backed up by technologies such as the Raspberry Pi and Arduino, for example. The talk closed with the conceptual idea that the majority of data, in the world today, is still largely unmeasured, and hoped that Azure would be an important platform in unlocking developers potential to measure previously untapped data.

2) Kevin Ashton. Inventor of the “Internet of Things”.

Kevin coined the term the Internet of Things (IoT), and gave a very good talk on what this means, as well as identifying certain ‘predictions’ for the future. For instance, that we, as a species, would survive climate change for one. He quickly noted that calling ‘BS’ on this particular one would be tricky should we suffer a doomsday style event at the hands of climate change (I don’t imagine the last thoughts of humanity to be, ‘oh, Kevin Ashton was so bloody wrong!’). Another interesting prediction; we would all own a self-driving car by 2030. Prototype examples already exist, such as Googles (and Apples) efforts, and the Tesla:

Google/Apple (Titan) Self Driving Cars
The Tesla

Self-driving cars being one of the cases in point, the IoT relates to how a whole new host of devices will now become ‘connected’. Besides cars rigged up to the internet, we are all aware of the hooking up of internal systems in our homes (heating, etc) and utility devices (the washing machine), as to always be online and accessible at a moments notice. This world isn’t coming per say, it’s essentially already here.

Pushing past this initial definition, Kevin was keen to stress that the IoT was not limited in its definition to just ‘the connecting of hardware to the internet’ only. Wiki sums this up quite nicely on this occasion, but software (services and analytics) that moves forward with hardware changes will ultimately change the way we live, work, shop and go about our daily lives. Whether this be data relayed from the fridge to google glasses (yes, you are out of milk!), or perhaps a self-driving car ordering ‘click and collect’ shopping and driving you to the collection point after work (not to mention triggering the heating x miles from home!). Software, and the analysis of the new kinds of data we can record from interconnected elements, will be a huge driving force in how our world changes:

Internet of Things (IoT)

Lastly, before I forget and move on, a key phrase voiced several times (although I cannot remember the exact speaker, so apologies for that, it was probably David Chappell) was to reset your defaults. Standard client/server architecture was discussed, and for those of us that are part of long running businesses this is what we are exclusively, or at least partially, dealing with on a daily basis still. However, the change to the use of mobile devices, tablets, etc, as clients and the cloud as the underpinning location for the services these clients communicate with is becoming the norm. For start-ups today, mobile first development and the cloud (Azure or Amazon Web Services (AWS)) are probably the initial go-to.

For some of us (speaking from a personal standpoint only), a major factor in our success as developers could simply be determined by understanding the cloud and getting the necessary experience to make the transition (for those who are not actively taking part in this world of course).

So, now we have the IoT, let’s talk security…

3) Graham Cluley. Security Analyst, grahamcluley.com.

Graham delivered a funny and insightful talk surrounding everyones’, ‘Oh my God, the horror, please kill me’ subject, the wonderful world of security.

In a nutshell, he argues (and certainly proves his point as you’ll read next) that the IoT will bring wonders to our world, but not without issues. We now have a scenario whereby a breadth of new devices have suddenly become internet connected. However, are the driving forces behind these changes the people who are used to dealing with the murky world of malware, viruses and hacking attempts (such as OS developers)? Probably not, is the initial answer. This is, of course, just a cultural divide between those used to trans-versing the security world and protecting devices from such attacks, and those tasked with bringing new devices to the interconnected world.

The hacking of self-driving cars (big topic it would seem) was discussed:

Fiat Chrysler Recalls

Also, the potential of hacking pacemakers was covered (bluetooth/wifi enabled), famously featured in the TV series Homeland and which actually lead to Vice President Dick Cheney’s cardiologist disabling the wireless functionality of his device:

Pacemaker Hacking
Could Pacemakers Be Hacked?

Although funny, the talk did indeed bring up a very serious issue. The ramifications could be catastrophic, depending on the types of devices that ultimately end up being exposed to the masses via the web. Essentially, as the IoT age develops, extra care must be taken to ensure that security is right on up there, in the hierarchy of priorities, when developing software for these devices.

4) Chris Bishop. Scientist and Lab Director, Microsoft Research.

The last talk I would personally like to discuss briefly was by Chris Bishop; there were a few great nuggets here that are well worth covering.

The idea of Machine Learning (not a topic I was overly familiar with for starters), Neural Networks and Pattern Recognition laid the foundation for a talk looking at the possibility of producing machines with human-level, or even super-human, intelligence.

The Microsoft Kinect was used to demonstrate hand-tracking software that, I have to admit, had an incredible amount of fidelity in recognising hand positions and shapes.

Lastly, a facial recognition demonstration that could estimate, with good accuracy, the emotional state of a person was kicked off for us all to see. Very, very impressive. There was most certainly an underlying feeling here (and as much was hinted at) that his kind of technology has many hurdles to jump. For instance, building something that can consume an image and accurately describe what is in that image is still a flaky concept, at best (and the difficulties of producing something capable of this are relatively vast).

Still, a greatly enjoyable talk! A book was touted, and I believe (please don’t shout at me if I’m wrong) this is the one:

Pattern Recognition and Machine Learning

After the morning Key Notes, a series of smaller talks and break-out sessions were available to us. Here’s how I spent my time…

Unity3D Grok Talk

Josh Taylor. Unity Technologies.

It’s my sincere hope that, on discovering this, my employer won’t decide to sack me! This was over lunch and was a self-indulgent decision I’m afraid! You’ll know from some of my historical posts that I have a keen interest in Unity3D (and have spent time making the odd modest prototype game here and there), and I was interested to see how Unity 5 was progressing, especially as a greater cohesive experience with Visual Studio had been promised.

In this short, 20 minute talk, we experienced how Visual Studio (finally) integrates nicely into the Unity3D content creation pipeline. Unity3D now defaults to using Visual Studio as the editor of choice, with Monodevelop being pushed aside. Apologies to anyone who likes Monodevelop, but I’ve never been able to get behind it. With wacky intellisense and with what I can only describe as a crash-tastic experience in past use, I haven’t seen anything yet to sway me from using Visual Studio. In fact, it was demonstrated that you can even use Visual Studio Code if you wish and, as it’s cross-platform, even Mac and Linux users can switch to this if they wish. More reasons to leave Monodevelop in the dust? It’s not for me to say really, go ahead and do what you’ve got to do at the end of the day!

In order to debug Unity projects in Visual Studio in the past a paid for plugin was required. This particular plugin has been purchased by Microsoft and is now available to all. Being able to easily debug code doesn’t sound like much, but trust me it’s like having a basic human right re-established – such good news!!!

The new licensing model was also commented on, a massive plus for everyone. The previous Free/Pro divide is no more; now everyone gets access to the lions share of the core features. You only need to start spending money as you make it (fair for Unity to ask for a piece of the pie if you start rolling in profit/expanding a team to meet the new demand). For me, this means I actually get to use the Unity Pro water effects, hoorah ;-).

Following this, I spent a bit of time last weekend watching the Unite 2015 Key Notes, discussing 2D game development enhancements, cloud based builds and Oculus support. Well worth a look if and when time allows:

Unite 2015 Key Notes

Plus, if Oculus technology interests you, then it’s definitely worth watching John Carmacks (formerly of ID Software, the mind behind Wolfenstein and Doom) Key Note from the Oculus Connect 2 event:

John Carmack Oculus Keynote

Very exciting times ahead for Unity3D I believe. Self-indulgence over, moving forward then…

Journey to the Intelligent Cloud

Corey Sanders. Director of Program Management, Azure.

Following the Unity3D talk, I made my way back to the ICC Auditorium (I missed a small section of this particular talk, but caught the bulk of it) to catch up on some basic examples of how the new Azure Portal can be used. This took the form of a brief overview of what’s available via the portal, essentially a primer session.

In my recent, personal work with Azure I’ve used the publishing capability within Visual Studio to great affect; it was very transparent and seamless to use by all accounts. A sample was provided within this particular session which demonstrated live coding changes, made in GitHub, being published back to a site hosted on Azure.

Going into a tangent….

Very much a personal opinion here, but I did find (and I wasn’t the only one) that a good portion of the content I wanted to see was a) on at the same time (the 1:15pm slot) and b) was during the core lunch period where everyone was ravenous, I’m a ‘hanger’ sufferer I’m afraid. C# with Mads Torgerson, ASP.NET 5, Nano Servers and Windows 10 (UWP) sessions all occupied this slot, which drove me a little nuts :-(. This felt like a scheduling issue if I’m honest. I’d be interested to hear from anyone who did (or didn’t) feel the same.

I was so disappointed to miss Mads Torgerson, I very much enjoyed the recent C# language features overview and would have loved to have made this breakout session! I did walk past him later in the day, and I hope he never reads this, but he seemed ridiculously tall (perhaps Godly C# skills made him appear several inches taller, who knows!). It doesn’t help that I’m on the shorter side either, I just wanted to be 5′ 11″, that’s all I ever wanted (break out the rack, I need to get stretching!). I should have said hello, but wimped out!

F# Language Breakout Session

Don Syme. Principal Researcher, Microsoft Research.

This was easily the part of the event that resonated the most with me, and strongly influenced the foray into F# that I undertook recently. Don Syme, the designer and architect of the F# language, took us through a quality primer of the syntax and how F# can be used (and scaled) for the cloud.

All of this aside, the most impressive part of the talk was a live demonstration of F# Type Providers. Again, this is fully covered in my previous post so I’ll just direct you to that, which in turn will aid me in cutting down what is now becoming a gargantuan post. In summary, the ability to draw information directly from web pages, rip data straight from files and databases, and combine and aggregate it all together using minimal code produces a terse, easy to understand and pretty darn good experience in my book. Even the code behind producing visual feedback, in the form of the charting API, is succinct; the bar really isn’t set too high for new starters to get involved.

If you decide to give anything a go in the near future, I would give F# the nod (followed closely, just a hair’s breadth away, by jQuery in my opinion). Certainly check it out if you get the chance.

Final Key Note

Professor Brian Cox. Physicist.
Krysta Svore. Senior Researcher, Microsoft Research.

The day proceeded in fast forward and, before we’d really had the chance to gather our thoughts, we were sitting in the main auditorium again faced by Professor Brian Cox, Krysta Svore and a menagerie of confused attendees staring at mathematical formulas outlining quantum theory.

Into the wonderful world of quantum computers we dance, and in my case, dragging my brain along from somewhere back yonder in a desperate attempt to keep up. Thankfully, I’m an avid TED talk fanatic and had, in the run up to the event, brushed up on a few quantum theory and quantum mechanics videos; lucky I did really. The content was dense but, for the most part, well put together and outlined the amazing (and potentially frightening) world of possibilities that quantum computers could unlock for us all.

Professor Brian Cox cruised through the theories we’d need to be intimate with in order to understand the onslaught of oncoming content surrounding quantum computers. In essence, a traditional ‘bit’, has a defined state (like a switch), on or off. However, and this is the simple essence of what they were trying to get to, traditional bits are reaching limitations that will prevent us from solving more complex problems, in a timely manner (you’ll see what I mean in a second). Therefore, qubits, born from quantum theory, are the answer.

Now, I’m not going to insult your intelligence and go into too much detail on a subject that I am clearly not an expert in. So, just in ‘laymen’s bullet points’, here is what I took from all that was said and done across the Key Note:

  • With bits, you are dealing with entities that can have a fixed state (0 or 1). A deterministic system if you will, that has limitations in its problem crunching power.
  • Qubits, however, take us into the realm of a probabilistic system. The qubit can be in a superposition of all of the allowed states, not just 0 or 1.
  • Therefore, the problem crunching powers of qubits are exponential in nature, but the probabilistic nature makes measuring them (and interactions involving them) difficult to get to grips with.

So is it worth fighting through the technical problems in order to harness qubits? What kind of gains are we talking about here?

Krystra Svore outlined an example that displayed that it would take roughly one billion years for a current super computer to crack (more complex than standard) RSA encryption. How long would it take a quantum computer you may ask? Significantly faster is the answer, estimated at around one hundred seconds in fact. This clearly defines for us the amazing problems we’ll be able to solve, whilst simultaneously illustrating the dangerous times that lay ahead from a security standpoint. Let’s just hope cryptography keeps up (I can see a few sniffs to suggest things are in the pipeline, so I will keep an eye out for news as it pops up).

So you want a quantum computer I hear you say! Hmmm, I wouldn’t put it on the Christmas list anytime soon. Due to the fact current quantum computers need to be super cooled (and from the pictures we got to see, didn’t look like you could hike around with it!), we’re not likely to get our hands directly on them in the near future.

Can you get your mitts on quantum simulators today? Apparently yes in the answer (completed untested links, just for you to peruse on your own, good luck):

QC Simulators
Project Liquid

Taking nothing away from the Key Note though, it was a concrete finish to an excellent event. Would I go again? You bet! Should we get the train next time instead of driving? Taking into account the mountains of free beer and wine on offer, of course! To finish up, before summarising the Expo itself, if you haven’t been and get the opportunity (in fact, actively seek the opportunity, enough said) then definitely book this in your calendar, thoroughly brilliant.

Expo

Very, very quickly, as I am acutely aware that your ability to focus on this post (if not already) must have completely diminished by this point, I wanted to describe what the Expo itself had to offer. If you’re still reading, give yourself a pat on the back!

One of the more compelling items we saw was the use of the new Lumia phone as a (kind of) desktop replacement attempt. Let’s get one thing straight, you’re not going to be doing hardcore software development using Visual Studio or any other intensive task on this device anytime soon. However, there was certainly enough evidence to suggest that basic productivity tasks would be possible using a mobile phone as a back bone to facilitate this.

The Lumia can be hooked up to a dock, akin to the Surface Pro 4 (the docks are subtly different apparently, so are not cross-compatible), and that allows it to be tied to a display device. You can also get a folding mouse and keyboard, for a very lightweight, on-the-go experience. Interesting certainly, but there is a definite horse-power issue that will prevent anyone working on anything remotely intensive from getting on board. Anyway, for those interested the link below will get you started:

Lumia Docking Station

I saw a few Surface Pros, and wondered whether we could potentially smuggle a few out of the Expo! Only kidding, no need to call the Police (or for anyone I work with thinking I am some kind of master criminal in the making) :-).

An Oculus demonstration booth was on the Expo floor, and displays were hooked up to show what the participants were experiencing. It was noted that a few of the people using the Oculus seemed to miss the point a bit, and kept their head completely still as they were transported through the experience. Once the heads started moving (to actually take in the world) you could visibly see people getting incredibly immersed. Alas, the queues were pretty darn large every time I made my way past, so I didn’t get a chance to experience it first-hand. One for the future.

There was also a programmable cocktail maker, an IoT masterpiece I think you’ll agree. A perfect union of hardware, software and alcohol, a visionary piece illustrating the future has arrived!

The next time an event like this comes around I will endeavour to get a post up in a timely fashion (which will vastly improve the content I hope).

Thanks for reading and a high five from me if you made it this far. Back to coding in the upcoming post I promise, until the next time, cheers from me (and would you believe it, it’s now Tuesday)!

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!