Saturday, 21 May 2016

Dependency Inversion Principle: Part 5 - Using DIP/IoC container

(Note: you should read Part4 - Refactoring Using DIP before in order to understand this section)

I can just stop after refactoring code in previous section. I don't really need to use a DIP/IoC container. However most containers will have some additional features which enable us to tidy up the class composition code. You can even write your own IoC container with the features you really need.

Most containers will have some kind of registers, where you can register abstractions(interfaces, abstract classes, or just normal classes), and their implementations. However, you would normally interact with the container so you can utilize its features.

In this section, I will use Simple Injector 3.1.4.0 as an example. Using this container I will refactor the class composition code from previous section. I will use type discovery or auto wiring feature from Simple Injector.
        internal static WebAnalytic CreateCompositionRoot()
        {
            string logFilePath = @"D:\log.txt";
            string webAddress = @"http://www.google.com";

            SimpleInjector.Container container = new SimpleInjector.Container();   
          
            container.Register<IWriterStream>(()=> new FileWriterStream(logFilePath));
            container.Register<IWebText>(() => new WebText(webAddress));
            container.Register<IConsole, ConsoleTerminal>();
            container.Register<ILogger, FileLogger>(SimpleInjector.Lifestyle.Singleton);
            container.Register<IScanner, TextScanner>();
            container.Register<WebAnalytic, WebAnalytic>();
            
            return container.GetInstance<WebAnalytic>();
        }
Firstly, I create a container, and then register all interfaces and their implementations. For IWriterStream and IWebText, the implementations are anonymous delegates, because we need to pass the string parameters, logFilePath and webAddress. I used those delegates to return FileWriterSteream and WebText respectively.

For IConsole, ILogger and IScanner, I register the implementation classes. And for ILogger I specifically marked the implementation lifestyle as singleton. One thing to notice that, you don't need to pass dependencies for FileLogger or TextScanner. The container will automatically resolve the dependencies based on the types you have registered. This feature is called type discovery or auto wiring. For example FileLogger has a dependency on IWriterStream, which will be automatically resolved to FileWriterStream, and TextScanner has a dependency on ILogger, which will be resolved to FileLogger.

Lastly, I self register the WebAnalytic. The container does not only register interfaces, but also normal classes. So every time we query the container for this class, like above return statement, it will create WebAnalytic instance by resolving all the dependencies first.

[Update]
You can get rid of the need to use lambda in above case, by abstracting the string or any primitive types into classes instead. For example instead of passing 'webAddress' and 'logFilePath', you can pass an implementation of interface called IValueProvider

        internal interface IValueProvider
        {
             string WebAdress { get; }
             string LogFilePath {get;}
        }

        internal class ConfigValue : IValueProvider
        {
            public string WebAdress 
            {
                 get
                {
                   return @"http://www.google.com";
                }
            }
          
            public string LogFilePath
            {
                get
                {
                   return @"D:\log.txt";
                }
            }
        } 

And now you can pass the implementation of the interface into the container instead

        internal static WebAnalytic CreateCompositionRoot()
        {
            SimpleInjector.Container container = new SimpleInjector.Container();   

            container.Register<IValueProvider, ConfigValue>();
            container.Register<IWriterStream, FileWriterStream>();
            container.Register<IWebText, WebText>();
            container.Register<IConsole, ConsoleTerminal>();
            container.Register<ILogger, FileLogger>(SimpleInjector.Lifestyle.Singleton);
            container.Register<IScanner, TextScanner>();
            container.Register<WebAnalytic, WebAnalytic>();
            
            return container.GetInstance<WebAnalytic>();
        }
Of course you will need to modify the implementation of FileWriterStream and WebText accordingly.

In this section, I only discuss briefly on the IoC container features. The code is also very simple and cannot display the rich features of IoC container. You can just choose any Ioc frameworks and learn the features they have and the problems they are trying to solve. For the purpose of learning DIP, what I have discussed so far should be enough.

Final remarks

All the source code for previous (Refactoring Using DIP) and this section (Using DIP/IoC Container) can be download from Github.

All the materials I discuss in this topic are from my coding experience, reading question-answer on Stack Overflow, blogs and articles I could find on the internet. My understanding on this topic may flaw and I am open to correction. My writing style sometimes can be prescriptive, which is not my intention. You can do whatever you want once you grasp the concept behind it, or you may disagree with my understanding.

There are some blog entries which give me some insights, so I will put it down here.
  1. Dot net trick - Inversion of Control Practical Usage
  2. Dot net trick - Dependency Injection IOC

Dependency Inversion Principle: Part 4 - Refactoring Using DIP

You have known the basic concepts of DIP, now it is time to apply it to the code. If the code is written without DIP principles, this means the code needs a refactoring by abstracting and inverting the dependencies. The code will normally have many interactions between classes. This mean that a class may have dependencies, but in turn the class will be the dependency of other class.

Refactoring the code using DIP will eventually create a tree structure which represents the class composition. Normally there will be one composition root, which is the class at the top of the tree.

Let us start with an example of the code which is not adhere to DIP.
internal class Program
    {
        static void Main(string[] args)
        {
            var webAnalytic = new WebAnalytic();
            webAnalytic.Run();
        }
    }

    internal class WebAnalytic
    {        
        public void Run()
        {
            string webAddress = "http://www.google.com";
            FileLogger.Instance.WriteLine(string.Format("Web text from {0}", webAddress));

            using (var client = new HttpClient())
            {
                string webText = client.GetStringAsync(webAddress).Result;

                var textScanner = new TextScanner();
                var reportText = textScanner.Scan(webText);

                Console.Write(string.Format("Result of scanning web text from {0}\n{1}", webAddress, reportText));
            }
            Console.ReadKey();
        }
    }

    internal class FileLogger
    {
        private string _filePath = @"D:\log.txt";

        private static FileLogger _instance;
        public static FileLogger Instance
        {
            get
            {
                return _instance ?? (_instance = new FileLogger());
            }
        }

        private FileLogger()
        {
        }

        public void WriteLine(string text)
        {
            using (var stream = File.AppendText(_filePath))
            {
                stream.Write(text + Environment.NewLine);
            }
        }
    }

    internal class TextScanner
    {
        public string Scan(string text)
        {
            var reportText = string.Format("Number of characters scanned: {0}", text.Length);
            //can be extended with more analysis
            FileLogger.Instance.WriteLine(reportText);
            return reportText;
        }
    }

The code download a text from a website and perform some analysis, for the simplicity just counting the word. There is also a logging feature. For the sake of learning, I will refactor the code step by step.
  1. Inverting Dependencies
  2. Abstracting Remaining Dependencies
  3. Configure Class Composition
You can follow the steps for initial learning, but once you master it, you can just do it one go.

1. Inverting Dependencies

The first task is inverting dependencies. The candidates are:
  • any new operator, or any instantiation
  • singleton or any global states
  • external functionalities or long running methods
Any new operator, or any instantiation
Any new operator is a candidate for inversion, even though not all of them. Classes which are used for storing data, entity or model classes, and normally the return type are exception.

There is one class can be inverted in WebAnalytic, which is TextScanner.
  ..  
  internal class WebAnalytic
  {
    private TextScanner _textScanner;
    public WebAnalytic(TextScanner textScanner)
    {
       _textScanner = textScanner;
    }
    ...
  }
  .. 
Singleton or global states
Additionally, every singleton or global state pattern need to be converted to explicit dependency injection instead. In the code, there are FileLogger singletons in both WebAnalytic and TextScanner. So in those classes, FileLogger need to be injected instead.
  ..  
  internal class WebAnalytic
  {
    private FileLogger _fileLogger;
    private TextScanner _textScanner;
    public WebAnalytic(FileLogger fileLogger, TextScanner textScanner)
    {
      _fileLogger = fileLogger;
      _textScanner = textScanner;
    }
    ...
  }
  .. 
  internal class TextScanner
  {
    private FileLogger _fileLogger;
    public TextScanner(FileLogger fileLogger)
    {
      _fileLogger = fileLogger;
    }
  }  
External functionalities or long running methods
Moreover, if below functionalities are found in any classes, they need to be abstracted and inverted, so the remaining functionality can be unit tested.
  • database access
  • network access
  • disk operation, eg. file read/write operation
  • display operation
  • any long running process
  • inter process communication
  • any other I/O operations
The functionality can be abstracted as interface, and the existing code will go to the implementation of the interface. Here is the example:
public class ComplexClass
{

  public void Process(string path)
  {
     ...
     string text = File.ReadAll(path);
     ...
  }  
  .... 
}
Since, the functionality is a disk operation, it need to be abstracted (e.g. interface) and inverted (e.g. dependency injection via constructor)
public interface IReader
{
  string Read(path);
}

public FileReader : IReader
{
  public string Read(string path)
  {
     return File.ReadAll(path);      
  }
}

public class ComplexClass
{
  private IReader _reader;   
  public CompleClass(IReader reader)
  {
    _reader = reader;
  }  

  public void Process(string path)
  {
     ...
     string text = reader.Read(path);
     ...
  }  
  ....
}
In above example, the functionality is abstracted using IReader interface, and the dependency, FileReader, is injected via ComplexClass constructor.

In the scenario where only function or method needs abstraction, you can use a generic delegate, Func<T> or Action instead of using interface.

Back to the code, Console class provides a display functionality, and this is abstracted using IConsole and implemented by a ConsoleTerminal class. The ConsoleTerminal then need to be injected via WebAnalytic constructor.
 internal interface IConsole
    {
        void Write(string text);
        void WaitKey();
    }

    internal class ConsoleTerminal : IConsole
    {
        void Write(string text)
        {
            Console.Write(text);
        }

        void WaitKey()
        {
            Console.ReadKey();
        }
    }
Also, HttpClient provides a network access, and this need to be abstracted and inverted. This will be abstracted using IWebText and implemented by WebText and injected via WebAnalytic constructor. The web address is passed to WebText as a constructor parameter.
    internal interface IWebText
    {
        string WebAddress { get; }
        string GetText();
    }

    internal class WebText : IWebText
    {
        public string WebAddress { get; private set; }
        public WebText(string webAddress)
        {
            WebAddress = webAddress;
        }

        public string GetText()
        {
            using (var client = new HttpClient())
            {
                return client.GetStringAsync(WebAddress).Result;
            }
        }
    }
Finally, there is also a file write operation on FileLogger, which needs an abstraction and inversion of control. This will be abstracted using IWriterStream and implemented by FileWriterStream, and injected via FileLogger constructor.
 internal interface IWriterStream
    {
        StreamWriter OpenStream();
    }

    internal class FileWriterStream : IWriterStream
    {
        private string _filePath;
        public FileWriterStream(string filePath)
        {
            _filePath = filePath;
        }

        StreamWriter OpenStream()
        {
            return File.AppendText(_filePath);
        }
    }
All above new classes are not unit-testable. They are just introduced to isolate external dependencies on the main classes. However, now the main classes, WebAnalytic and FileLogger are unit-testable. Those main classes constructor need a revision to accept the new dependencies. Here is the complete code after refactoring everything above.
internal class Program
    {
        static void Main(string[] args)
        {
            var webAnalytic = new WebAnalytic();
            webAnalytic.Run();
        }
    }

    internal class WebAnalytic
    {
        private FileLogger _fileLogger;
        private TextScanner _textScanner;
        private IConsole _console;
        private IWebText _webText;

        public WebAnalytic()
            : this(new ConsoleTerminal(), new WebText("http://www.google.com"), new FileLogger(), new TextScanner())
        {
        }

        public WebAnalytic(IConsole console, IWebText webText, FileLogger fileLogger, TextScanner textScanner)
        {
            _console = console;
            _webText = webText;
            _fileLogger = fileLogger;            
            _textScanner = textScanner;
        }

        public void Run()
        {
            _fileLogger.WriteLine(string.Format("Web text from {0}", _webText.WebAddress));
            string webText = _webText.GetText();
            var reportText = _textScanner.Scan(webText);

            _console.Write(string.Format("Result of scanning web text from {0}\n{1}", _webText, reportText));
            _console.WaitKey();
        }
    }

    internal interface IWebText
    {
        string WebAddress { get; }
        string GetText();
    }

    internal class WebText : IWebText
    {
        public string WebAddress { get; private set; }
        public WebText(string webAddress)
        {
            WebAddress = webAddress;
        }

        public string GetText()
        {
            using (var client = new HttpClient())
            {
                return client.GetStringAsync(WebAddress).Result;
            }
        }
    }

    internal interface IConsole
    {
        void Write(string text);
        void WaitKey();
    }

    internal class ConsoleTerminal : IConsole
    {
        void Write(string text)
        {
            Console.Write(text);
        }

        void WaitKey()
        {
            Console.ReadKey();
        }
    }

    internal interface IWriterStream
    {
        StreamWriter OpenStream();
    }

    internal class FileWriterStream : IWriterStream
    {
        private string _filePath;
        public FileWriterStream(string filePath)
        {
            _filePath = filePath;
        }

        StreamWriter OpenStream()
        {
            return File.AppendText(_filePath);
        }
    }

    internal class FileLogger
    {
        private IWriterStream _writerStream;

        public FileLogger()
            : this(new FileWriterStream(@"D:\log.txt"))
        {
        }

        public FileLogger(IWriterStream writerStream)
        {
            _writerStream = writerStream;
        }

        public void WriteLine(string text)
        {
            using (var stream = _writerStream.OpenStream())
            {
                stream.Write(text + Environment.NewLine);
            }
        }
    }

    internal class TextScanner
    {
        private FileLogger _fileLogger;

        public TextScanner()
            : this(new FileLogger())
        {
        }

        public TextScanner(FileLogger fileLogger)
        {
            _fileLogger = fileLogger;
        }

        public string Scan(string text)
        {
            var reportText = string.Format("Number of characters scanned: {0}", text.Length);
            //can be extended with more analysis
            _fileLogger.WriteLine(reportText);
            return reportText;
        }
    }
One thing to note in the code, every classes have two constructors, one with dependencies, and another one is a parameterless constructor. The later one is used to inject dependencies into a class. This is not an ideal solution, as the class will depend on the implementation, and not just depends on the abstraction. Some developers will felt suffice at this stage, as you can write unit tests for the classes, by using the constructor with dependencies, so the code is fully testable. However, in this discussion this pattern will be used as prelude to class composition introduced shortly.

2. Abstracting Remaining Dependencies

All dependencies are now inverted, but not all of them are abstracted. If they are not abstracted, the code will be glued to the implementation. In the code, WebAnalytic still has dependencies on FileLogger and WebScanner. ILogger and IScanner will be introduced to abstract the classes respectively.
 internal class Program
    {
        static void Main(string[] args)
        {
            var webAnalytic = new WebAnalytic();
            webAnalytic.Run();
        }
    }

    internal class WebAnalytic
    {
        private ILogger _logger;
        private IScanner _scanner;
        private IConsole _console;
        private IWebText _webText;

        public WebAnalytic()
            : this(new ConsoleTerminal(), new WebText("http://www.google.com"), new FileLogger(), new TextScanner())
        {
        }

        public WebAnalytic(IConsole console, IWebText webText, ILogger logger, IScanner scanner)
        {
            _console = console;
            _logger = logger;
            _webText = webText;
            _scanner = scanner;
        }

        public void Run()
        {
            _logger.WriteLine(string.Format("Web text from {0}", _webText.WebAddress));
            string webText = _webText.GetText();
            var reportText = _scanner.Scan(webText);

            _console.Write(string.Format("Result of scanning web text from {0}\n{1}", _webText, reportText));
            _console.WaitKey();
        }
    }

    internal interface ILogger
    {
        string WriteLine(string text);
    }

    internal interface IScanner
    {
        string Scan(string text);
    }

    internal interface IWebText
    {
        string WebAddress { get; }
        string GetText();
    }

    internal class WebText : IWebText
    {
        public string WebAddress { get; private set; }
        public WebText(string webAddress)
        {
            WebAddress = webAddress;
        }

        public string GetText()
        {
            using (var client = new HttpClient())
            {
                return client.GetStringAsync(WebAddress).Result;
            }
        }
    }

    internal interface IConsole
    {
        void Write(string text);
        void WaitKey();
    }

    internal class ConsoleTerminal : IConsole
    {
        void Write(string text)
        {
            Console.Write(text);
        }

        void WaitKey()
        {
            Console.ReadKey();
        }
    }

    internal interface IWriterStream
    {
        StreamWriter OpenStream();
    }

    internal class FileWriterStream : IWriterStream
    {
        private string _filePath;
        public FileWriterStream(string filePath)
        {
            _filePath = filePath;
        }

        StreamWriter OpenStream()
        {
            return File.AppendText(_filePath);
        }
    }

    internal class FileLogger: ILogger
    {
        private IWriterStream _writerStream;

        public FileLogger(): this(new FileWriterStream(@"D:\log.txt"))
        {
        }

        public FileLogger(IWriterStream writerStream)
        {
            _writerStream = writerStream;
        }

        public void WriteLine(string text)
        {
            using (var stream = _writerStream.OpenStream())
            {
                stream.Write(text + Environment.NewLine);
            }
        }
    }

    internal class TextScanner: IScanner
    {
        private ILogger _logger;

        public TextScanner()
            : this(new FileLogger())
        {
        }

        public TextScanner(ILogger logger)
        {
            _logger = logger;
        }

        public string Scan(string text)
        {
            var reportText = string.Format("Number of characters scanned: {0}", text.Length);
            //can be extended with more analysis
            _logger.WriteLine(reportText);
            return reportText;
        }
    }
In some other code base you may want to split some functionalities into their own classes, aligned with Single Responsibility principles. You can abstract the functionalities into an interface, and move the codes into an implementation class, and inject the dependency via main class's constructor. This makes the code more manageable and the new classes can be unit-tested separately from the main class.

3. Configure Class Composition

In the code, most classes have two constructors. The parameterless contructors are used to specify the implementation of the dependencies, and this basically makes the classes still glue to the implementation and not the abstraction. In order to fully comply with dependency inversion principles, the next refactoring step is removing the parameterless constructors, and configuring class composition instead.

Below is the structure of the class composition.
WebText and FileStreamWriter have dependencies on webAddress and filePath, which are of string type. FileLogger depends on IWriterStream, which is implemented by FileStreamWriter. TextScanner depends on ILogger, which is implemented by FileLogger. Finally, the composition root, WebAnalytic, depends on ILogger, IScanner, IWebText and IConsole and are implemented by FileLogger, TextScanner, WebText, and ConsoleTerminal respectively.

In the root application , I create a private method that return the composition root class, and the whole class composition can be performed inside this method. The method is then called from a main program. Alternatively, you can do all above just in a main program. Here is the complete code after refactoring:
 internal class Program
    {
        static void Main(string[] args)
        {
            WebAnalytic webAnalytic = CreateCompositionRoot();
            webAnalytic.Run();
        }

        internal static WebAnalytic CreateCompositionRoot()
        {
            string logFilePath = @"D:\log.txt";
            string webAddress = @"http://www.google.com";

            IWriterStream writerStream = new FileWriterStream(logFilePath);
            IWebText webText = new WebText(webAddress);
            IConsole console = new ConsoleTerminal();
            ILogger logger = new FileLogger(writerStream);                        
            IScanner scanner = new TextScanner(logger);

            return new WebAnalytic(console, webText, logger, scanner);
        }
    }

    internal class WebAnalytic
    {
        private ILogger _logger;
        private IScanner _scanner;
        private IConsole _console;
        private IWebText _webText;

        public WebAnalytic(IConsole console, IWebText webText, ILogger logger, IScanner scanner)
        {
            _console = console;
            _logger = logger;
            _webText = webText;
            _scanner = scanner;
        }

        public void Run()
        {
            _logger.WriteLine(string.Format("Web text from {0}", _webText.WebAddress));
            string webText = _webText.GetText();
            var reportText = _scanner.Scan(webText);

            _console.Write(string.Format("Result of scanning web text from {0}\n{1}", _webText, reportText));
            _console.WaitKey();
        }
    }

    internal interface ILogger
    {
        string WriteLine(string text);
    }

    internal interface IScanner
    {
        string Scan(string text);
    }

    internal interface IWebText
    {
        string WebAddress { get; }
        string GetText();
    }

    internal class WebText : IWebText
    {
        public string WebAddress { get; private set; }
        public WebText(string webAddress)
        {
            WebAddress = webAddress;
        }

        public string GetText()
        {
            using (var client = new HttpClient())
            {
                return client.GetStringAsync(WebAddress).Result;
            }
        }
    }

    internal interface IConsole
    {
        void Write(string text);
        void WaitKey();
    }

    internal class ConsoleTerminal : IConsole
    {
        void Write(string text)
        {
            Console.Write(text);
        }

        void WaitKey()
        {
            Console.ReadKey();
        }
    }

    internal interface IWriterStream
    {
        StreamWriter OpenStream();
    }

    internal class FileWriterStream : IWriterStream
    {
        private string _filePath;
        public FileWriterStream(string filePath)
        {
            _filePath = filePath;
        }

        StreamWriter OpenStream()
        {
            return File.AppendText(_filePath);
        }
    }

    internal class FileLogger : ILogger
    {
        private IWriterStream _writerStream;

        public FileLogger(IWriterStream writerStream)
        {
            _writerStream = writerStream;
        }

        public void WriteLine(string text)
        {
            using (var stream = _writerStream.OpenStream())
            {
                stream.Write(text + Environment.NewLine);
            }
        }
    }

    internal class TextScanner : IScanner
    {
        private ILogger _logger;

        public TextScanner(ILogger logger)
        {
            _logger = logger;
        }

        public string Scan(string text)
        {
            var reportText = string.Format("Number of characters scanned: {0}", text.Length);
            //can be extended with more analysis
            _logger.WriteLine(reportText);
            return reportText;
        }
    }
Most application will only need one class composition, however it is quite possible in some applications you may want to create multiple class compositions.

All code from this section, and also next section, can be downloaded from Github. I almost finish here. However, the discussion is not complete without explaining the role of DIP/IoC container in the refactoring process. I will discuss this topic in the next section.

Dependency Inversion Principle: Part 3 - Dependency Inversion Methods

After various parts of the class have been abstracted, the next thing to do is inverting the dependencies. The actual implementation of the abstraction, or dependencies, need to be provided from outside of the class. By doing so, the class now does not depend on the implementation, but only the abstraction of it.

In section one, I use constructor dependency injection as the dependency inversion method. In this section, I will discuss various methods of dependency inversion methods.

Here the list of dependency inversion methods:
  1. Using Dependency Injection
  2. Using Global States
  3. Using Indirection
Below, I will explain each of the methods.

1. Using Dependency Injection

Using Dependency Injection(DI), is where the dependency is injected directly to a class via its public members. The dependency can be injected into class's constructor (Contructor Injection), set property (Setter Injection), method (Method Injection), events, index properties, fields and basically any members of the class which are public. I generally don't recommended to use fields because exposing fields are not considered a good practice in Object-Oriented programming, as you can achieve the same thing using properties. Using index properties for dependency injection is also a rare case, so I will not explain it further.
Constructor Injection
I used mostly Constructor Injection. Using Constructor Injection can also leverage on some features in IoC container, such as auto-wiring or type discovery. I will discuss about IoC container in section 5 later. Below is an example of Construction Injection:
public class HighLevelModule
{
  private readonly IOperation _operation;

  public HighLevelModule(IOperation operation)
  {
    _operation = operation;
  }

  public void Call()
  {
    _operation.Send();
  }
}
Setter Injection
Setter and Method Injection are used to inject dependencies after the construction of the object. This can be seen as disadvantages when using along with IoC container(will be discussed in section 5). However if you don't use IoC container, they achieve the same thing as the Constructor Injection. The other benefit of Setter or Method Injection is to allow you to alter the dependency on the runtime, and they can be used in complement of Constructor injection. Below is an example of Setter Injection, which allow you to inject one dependencies at a time:
public class HighLevelModule
{
  public IOperation Operation { get; set; }

  public void Call()
  {
    Operation.Send();
  }
}
Method Injection
The Method Injection allow you to set multiple dependencies at the same time. Below is the example of Method Injection:
public class HighLevelModule
{
  private readonly IOperation _operationOne;
  private readonly IOperation _operationTwo;

  public void SetOperations(IOperation operationOne, IOperation operationTwo)
  {
    _operationOne = operationOne;
    _operationTwo = operationTwo;
  }

  public void Call()
  {
    _operationOne.Send();
    _operationTwo.Send();
  }
}
When using Method Injection, the dependencies that are passed as arguments will be persisted in the class, e.g as fields or properties, for later use. When passing some classes or interfaces in the method and to be used just in the method, this does not count as Method Injection.
Using Events
Using Events is limited only for delegate type injection, and this is only appropriate where subscription and notificatin model is required, and the delegate must not return any value, or just returning void. The caller wil subsribe a delegate to the class that implements the event, and there can be multiple subscribers. The event injection can be performed after the object construction. Injecting events via constructor is uncommon. Below is an example of event injection.
public class Caller
{ 
  public void CallerMethod()
  {
    var module = new HighLevelModule();
    module.SendEvent += Send ;

    ...
  }

  public void Send()
  {
    //this is the method injected into HighLevelModule
  }
}

public class HighLevelModule
{
  public event Action SendEvent = delegate {};

  public void Call()
  {
    SendEvent();
  }
}

In general, my mantra is always use Constructor Injection if nothing compelling to use Setter or Method Injection, and this is alaso to enable us to use IoC container later.

2. Using Global States

Instead of injected directly into the class, the dependency can be retrieved from a global state from inside the class. The dependency can be injected into the global states and later accessed from inside the class.

  public class Helper
  {
    public static IOperation GlobalStateOperation { get; set;}
  }

  public class HighLevelModule
  {
    public void Call()
    {
       Helper.GlobalStateOperation.Send();
    }
  }
   
  public class Caller
  {
    public void CallerMethod()
    {
      Helper.GlobalStateOperation = new LowLevelModule();

      var highLevelModule = new HighLevelModule();
      highLevelModule.Call();
    }
  }  
}

Global states can be represented as properties, methods or even fields.The important bit is that the underlying value has public setter and getter. The setter and getter can be in the form of methods instead of properties.

If the global state has only getter (e.g. singleton), the dependency is not inverted. Using global states to invert dependencies is not recommended, as it makes dependencies less obvious, and hides them inside the class.

3. Using Indirection

If you are using Indirection, you don't pass dependency directly into the class. Instead you pass an object that capable of creating or passing the implementation of the abstraction for you. This also means that you create another dependency for the class. The type of object you pass into the class can be:
  • Registry/Container object
  • Factory object
You can choose whether to pass the object directly (Dependency Injection) or using Global States.
Registry/Container object
If you use a register, this often called Service Locator Pattern, then you can query the register to return an implementation of an abstraction(e.g. interface). However, you will need to register the implementation first from outside the class. You can also use a container to wrap up the registry like many IoC container frameworks do. A container normally has additional features such type discovery or auto-wiring, so when you register an interface and its implementation, you don't need to specify the dependencies of the implementation class. When you query the interface, the container will be able to return the implementation class instance by resolving all its dependencies first. Of course, you will need to register all the dependencies first.

In the early days when IoC container frameworks just sprung up, the container was often implemented as a Global state or Singleton instead of explicitly passing it into a class, and this was now considered as anti-pattern. Here is an example of using a container type object:

public interface IOperation
{
  void Send();
}

public class LowLevelModule: IOperation
{
  public LowLevelModule()
  {
    Initiate();
  }

  private void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}

public class HighLevelModule
{
  private readonly Container _container;

  public HighLevelModule(Container container)
  {
    _container = container;
  }

  public void Call()
  {
    IOperation operation = _container.Resolvel<IOperation>();
    operation.Send();
  }
}

public class Caller
{
  public void UsingContainerObject()
  {
     //registry the LowLevelModule as implementation of IOperation
     var register  = new Registry();
     registry.For<IOperation>.Use<LowLevelModule>();

     //wrap-up registry in a container
     var container = new Container(registry);
      
     //inject the container into HighLevelModule
     var highLevelModule = new HighLevelModule(container);
     highLevelModule.Call();     
  }
}


You can even make HighLevelModule depends on the abstraction of the container, but this step is not necessary.

Moreover, using a container or registry everywhere in the classes may not be a good idea, as this makes it less obvious what the class's dependencies are.
Factory object
The difference between using a register/container and a factory object is that when using a register/container you need to register the implementation class before you can query it, while using a factory you don't need to do that as the instantiation is hardcoded in the factory implementation. Factory object is not neccesary to have 'factory' as parts of its name. It can be just a normal class that return an abstraction (e.g interface).

Moreover, because LowLevelModule instantiation is hardcoded in the factory implementation, having HighLevelModule depends on the factory will not invert the LowLevelModule dependency. In order to invert the dependency, HighLevelModule needs to depend on the factory abstraction instead, and the factory object needs to implement that abstraction. Here is an example of using a factory object:

public interface IOperation
{
  void Send();
}


public class LowLevelModule: IOperation
{
  public LowLevelModule()
  {
    Initiate();
  }

  private void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}

public interface IModuleFactory
{
   IOperation CreateModule();
}

public class ModuleFactory: IModuleFactory
{
  public IOperation CreateModule()
  {
      //LowLevelModule is the implementation of the IOperation, 
      //and it is hardcoded in the factory. 
      return new LowLevelModule();
  }
}

public class HighLevelModule
{
  private readonly IModuleFactory _moduleFactory;

  public HighLevelModule(IModuleFactory moduleFactory)
  {
    _moduleFactory = moduleFactory;
  }

  public void Call()
  {
    IOperation operation = _moduleFactory.CreateModule();
    operation.Send();
  }
}

public class Caller
{
  public void CallerMethod()
  {
     //create the factory as the implementation of abstract factory
     IModuleFactory moduleFactory = new ModuleFactory();
      
     //inject the factory into HighLevelModule
     var highLevelModule = new HighLevelModule(moduleFactory);   
     highLevelModule.Call();  
  }
}

My recommendation is to use indirection sparingly. Service Locator Pattern, is seen as anti-pattern nowadays. However from time to time you may need to use a factory object to create the dependencies for you. My Ideal is to stay clear from using Indirection, unless it is proven necessary.

Besides the implementation of abstraction (interface, abstract class or delegate), we normally can also inject dependencies for primitive type such as Boolean, int, double, string or just a class which contain only properties.

Dependency Inversion Principle: Part 2 - Abstraction Methods

The first activity in implementing DIP is to apply abstractions to the parts of the codes. In C# worlds, there are a couple ways to do this:
  1. Using an Interface
  2. Using an Abstract Class
  3. Using a Delegate
First, an interface is solely used to provide an abstraction, while an abstract class can also be used to provide some shared implementation details. Lastly, a delegate provides an abstraction for one particular function or method.

As a side note, it is a common practice to mark a method as virtual, so the method can be mocked when writing unit tests for the calling class. However this is not the same as applying an abstraction. Marking a method as virtual just makes it overridable, so the method can be mocked and this can be useful for testing purposes.

My preference is to use an interface for an abstraction purpose. I use an abstract class only if there is a shared implementation detail between two or more classes. Even that, I will make sure that the abstract class implements an interface for the actual abstraction. In section 1, I already give examples of applying abstractions using interfaces. In this section, I will give other examples using an abstract class and a delegate.

Using an Abstract Class

Using the example in section 1, I just need to change the interface IOperation to an abstract class, OperationBase.
public abstract class OperationBase
{
  public abstract void Send();
}

public class LowLevelModule: OperationBase
{
  public LowLevelModule()
  {
    Initiate();
  }

  private void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}

public class HighLevelModule
{
  private readonly OperationBase _operation;

  public HighLevelModule(OperationBase operation)
  {
    _operation = operation;
  }

  public void Call()
  {
    _operation.Send();
  }
}

The above codes are equivalent to using an interface. I normally only use abstract classes if there is a shared implementation detail. For example, if HighLevelModule can use either LowLevelModule or AnotherLowLevelModule, and both classes have a shared implementation detail, then I will use an abstract class as a base class for both. The base class will implement IOperation, which is the actual abstraction.
public interface IOperation
{
  void Send();
}

public abstract class OperationBase: IOperation
{
  public OperationBase()
  {
    Initiate();
  }

  private void Initiate()
  {
    //do initiation before sending, also shared implementation in this example
  }

  public abstract void Send();
}

public class LowLevelModule: OperationBase
{
 
  public void Send()
  {
    //perform sending operation
  }
}

public class AnotherLowLevelModule: OperationBase
{
  
  public void Send()
  {
    //perform another sending operation
  }
}

public class HighLevelModule
{
  private readonly IOperation _operation;

  public HighLevelModule(IOperation operation)
  {
    _operation = operation;
  }

  public void Call()
  {
    _operation.Send();
  }
}


Using a Delegate

A single method or function can be abstracted using a delegate. Generic delegate Func<T> or Action can be used for this purpose.
public class Caller
{ 
  public void CallerMethod()
  {
    var module = new HighLevelModule(Send);
    ...
  }

  public void Send()
  {
    //this is the method injected into HighLevelModule
  }
}

public class HighLevelModule
{
  private readonly Action _sendOperation;

  public HighLevelModule(Action sendOperation)
  {
    _sendOperation = sendOperation;
  }

  public void Call()
  {
    _sendOperation();
  }
}

Alternatively, you can create your own delegate and give a meaningful name to it.

public delegate void SendOperation();

public class Caller
{ 
  public void CallerMethod()
  {
    var module = new HighLevelModule(Send);
    ...
  }

  public void Send()
  {
    //this is the method injected into HighLevelModule
  }
}

public class HighLevelModule
{
  private readonly SendOperation _sendOperation;

  public HighLevelModule(SendOperation sendOperation)
  {
    _sendOperation = sendOperation;
  }

  public void Call()
  {
    _sendOperation();
  }
}

The benefit of using generic delegates is that we don't need to create or implement a type, e.g interfaces and classes, for the dependencies. We can just use any methods or functions from the caller context or from anywhere else.

In this section, I have discussed abstraction methods using an abstract class and a delegate. Applying an abstraction using an interface has been covered in the previous section. Beside applying abstractions, the other activity in implementing DIP is to invert class dependencies. In the next section, I will discuss various dependency inversion methods.

Saturday, 7 May 2016

Dependency Inversion Principle: Part 1 - Concepts

In this article I will discuss about one of SOLID principles in the Object Oriented Programming paradigm, which is ‘D” or Dependency Inversion Principle (DIP) or also known as Inversion of Control (IoC).

The topic is divided into several blogs entries as outline above because of its length. It is recommended to follow the exact order of the outline. The discussion is presented with many examples in C# codes to help readers to grasp the underlying concepts.

What is DIP?

The principle states:
  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend on details. Details should depend on abstractions.
For example, the code below does not comply to above principles:
public class HighLevelModule
{
  private readonly LowLevelModule _lowLowelModule;
 
  public HighLevelModule()
  {
    _lowLevelModule = new LowLevelModule();   
  }

  public void Call()
  {
    _lowLevelModule.Initiate();
    _lowLevelModule.Send();
  }
}

public class LowLevelModule
{
  public void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}

In the above codes, HighLevelModule depends directly on LowLevelModule and this does not follow the first point of DIP. Why does this matters? The direct and tightly coupled relationship between the two makes it harder to create unit tests on HighLevelModule in isolation from LowLevelModule. You are forced to test HighLevelModule and LowLevelModule at the same time because they are tightly coupled.

Note, it is still possible to do unit tests on HighLevelModule in isolation using testing framework which performs .NET CLR interception, such as TypeMock Isolator. Using this framework, it is possible to alter LowLevelModule behavior on testing. However, I don't recommended this practice for two reasons. Firstly, using CLR interception in testing defies the reality of the code: the reliance of HighLevelModule on LowLevelModule. At worst, the testing can give false positive results. Secondly, that practice may discourage us to learn the skills to write clean and testable code.

How do we apply DIP?

The first point of DIP suggest us to apply two things at the same time to the codes:
  • Abstraction,
  • Dependency Inversion or Inversion of Control
Firstly, LowLevelModule need to be abstracted and HighLevelModule will depend on the abstraction instead. Different methods of abstraction will be discussed in the next section. For the example below, I will use an interface for the abstraction. An IOperation interface is used to abstract LowLevelModule.
public interface IOperation
{
  void Initiate();
  void Send();
}

public class LowLevelModule: IOperation
{
  public void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}
Secondly, because HighLevelModule will solely depend on IOperation abstraction, we can't have new LowLevelModule() inside the HighLevelModule class anymore. LowLevelModule need to be injected into HighLevelModule class from the caller context. The dependency, LowLevelModule , need to be inverted. This is where the terminology 'Dependency Inversion' and 'Inversion of Control' come from.

The implementation of the abstraction,LowLevelModule, or behavior need to be passed from outside of HighLevelModule, and the process of moving this from inside to outside of the class is called inversion. I will discuss different methods of dependency inversion in the section 3. In the example below, dependency injection via constructor will be used.
public class HighLevelModule
{
  private readonly IOperation _operation;

  public HighLevelModule(IOperation operation)
  {
    _operation = operation;
  }

   public void Call()
  {
    _operation.Initiate();
    _operation.Send();
  }
}
We have decoupled the HighLevelModule and LowLevelModule from each other, and both now depend on the abstraction IOperation. The Send method behavior can be controlled from outside of the class, by passing any implementation choices of IOperation, e.g LowLevelModule

However, it is not finished yet. The code still does not comply with the second point of DIP. The abstraction should not depend on the detail or implementation. The Initiate method in IOperation is in fact an implementation detail of LowLevelModule, which is used to prepare the LowLevelModule before it can perform Send operation.

What I have to do is remove it from the abstraction,IOperation, and consider this as part of LowLevelModule implementation details. I can include the Initiate operation inside LowLevelModule constructor. This allow the operation to be a private method, limiting its access to within the class.
public interface IOperation
{
  void Send();
}

public class LowLevelModule: IOperation
{
  public LowLevelModule()
  {
    Initiate();
  }

  private void Initiate()
  {
    //do initiation before sending
  }
  
  public void Send()
  {
    //perform sending operation
  }
}

public class HighLevelModule
{
  private readonly IOperation _operation;

  public HighLevelModule(IOperation operation)
  {
    _operation = operation;
  }

  public void Call()
  {
    _operation.Send();
  }
}

In the next section I will discuss different methods of abstraction available to us in C# world to perform Dependency Inversion.

Saturday, 16 April 2016

Parallel Task With Time Expiration (Pseudo Timeout)

Hi, today I will write about mini task I was doing at work. To keep the story short, I have been asked to refactor code to control the maximum concurrency spawned from a method, and the method should run in a certain amount of time.

Here is the code before refactoring:

  public void PerformMultiTask(IEnumerable<string> ids)
  {
    foreach(string id in ids)
    {
      Task.Run(()=>PerformSingleTask(id));
    }
  }

The reason for the time limit is because the scheduler which triggers the method will run in intervals. So, we need to make sure that method execution finishes before the scheduler starts again. We also want the ability to control the concurrency of the execution.

Here is the code after refactoring:

  public void PerformMultiTask(
    int timeLimitInSeconds, 
    int maxConcurrency,
    IEnumerable<string> ids)
  {
     DateTime timeLimit = DateTime.UtcNow.Add(new TimeSpan(0,0,0,timeLimitInSeconds));
                        
     Parallel.ForEach(
      ids,
      new ParallelOptions() { MaxDegreeOfParallelism = maxConcurrency },
      (id, loopState) =>
      {
        if (DateTime.UtcNow < timeLimit)
          PerformSingleTask(id);
        else
          loopState.Stop();
      });
  }

I use Parallel.ForEach method which accepts three parameters:
  1. the list IEnumerable<T>
  2. ParallelOptions instance
  3. Action(T,ParallelLoopState)
In the above example T is a string type. We create a ParallelOptions instance and specify MaxDegreeOfParallelism to control the maximum concurrency of the parallel loop. The variable loopstate is a ParallelLoopState instance, which is passed as an argument and used by the action to stop the whole parallel loop, once the expiration(or time Limit) has been reached.

Feel free to comment or to suggest improvement of the code.