Design Patterns

Inversion of Control

I spent a few weeks earlier this year doing some research on Castle Windsor (a specific IOC container) to implement it into a solution at work. In this and future posts, I plan to discuss some of the things I’ve learned over the course of that research.

Inversion of control (IOC) is a way to link together classes with different dependencies at run time instead of explicitly creating the dependencies in code.  A good analogy to think of is an IOC container is like glue.  It can take classes built in code and combine them together to construct one or more objects.  It doesn’t really add functionality to the application, but instead binds and holds everything together.

Dependency injection and inversion of control often get confused and interchanged as terms.  I like to think of it this way.  Dependency injection is really an abstract design pattern used in a class by class basis. It allows other objects to be “injected” or passed into an individual class.  IOC is a pattern whereby a container takes a plethora of classes and combines them all together to construct some object tree from them all, thereby making dependency injection easier to fulfill.  The container for the IOC pattern is often structured  using a factory design pattern.

Imagine there are several classes all utilizing dependency injection.  Each class has 2 or 3 parameters.  Now, for every class that needs to be constructed for each parameter passed in, those also have parameters that need to be constructed and passed in.  This get’s complex fast.  Just think of it as a huge object tree that continues to get linked and put together. The more complex the program, the larger the number of dependencies to fulfill, and the more difficult the object tree becomes to construct.

This is where IOC steps in to help.  By relying on the IOC container, it can resolve those references and automatically create the objects for us after it has been properly configured.

IOC containers work in a 3 step process.

  1. Component registration, also known as installation in some frameworks
  2. Object resolution, also known as resolving, or constructing an object
  3. Disposal of objects

Here’s a brief description of each step.  I will post some more concrete examples of working with Castle Windsor later which should help these make more sense.

In the registration process a set of rules are defined which determine where a specific implementation of a class will map.  For example, let’s say we are using the FordTaurus example from my dependency injection post.  We could tell the container that whenever it encounters an Engine class, it should construct a V6Engine for it.

In the object resolution process, this is where most of the work for the container will go.  Typically this is one or more calls to have the container construct some object for the program.  The container will resolve any unknown classes and pass them in as appropriate as defined by the registration process.

The last step is to dispose of the objects.  This is either telling the container to release the object so it isn’t tracked anymore, or to simply do any clean up logic for the object itself.

The concept seems very abstract at first. In a future post, I will show an example and put this into action. Hopefully, you will be able to see the benefits and be able to try it out in your next project too.

Advertisements

C# Singleton Pattern

The singleton pattern is an effective way to limit the existence of a class to a single instance.  Example areas where this pattern are beneficial would be a global context for an application, global application settings, or a global logging solution.

1 public class Singleton { 2 3 // Constructor is made private in order to avoid 4 // other code from creating an instance of the 5 // class. 6 private Singleton() {} 7 8 // A private variable holds the single instance 9 // to the class. 10 private static Singleton m_instance; 11 public static Singleton Instance { 12 get { 13 // If the singleton private variable 14 // has not yet been initialized with 15 // an instance of the singleton class, 16 // the singleton should be created and 17 // returned. Otherwise, the previously 18 // created singleton should be returned. 19 if (m_instance == null) 20 m_instance = new Singleton(); 21 22 return m_instance; 23 } 24 } 25 }

A common misusage of this pattern would be a class filled with static methods and variables. While this is technically a singleton, if the object is required to keep state, it is best to be left as a non-static class with a single instance.  The primary advantage is is to allow for interfacing and potential future instancing if the class were to grow beyond it’s single instance.

Another common problem is instantiating the singleton class is by using a static constructor.  While this does effectively create a singleton, if the singleton where to throw an exception during creation, the static constructor would always throw the exception rendering any static variables or methods on the class useless.  So, care must be taken if a static constructor is to be used.