Dependency Injection Techniques Explained - Implementing StructureMap

In the previous article, we discussed what Dependency Injection and Inversion of Control are and also discussed how DI is handled in projects without containers. Then we looked at a simple way to handle the dependencies by configuring the DLL in the application configuration and injecting that into our code without much effort.

Here first we will discuss how to use a StructureMap to do that. This article is not going to explain everything supported by a StructureMap (SM). This article is for understanding the basics of the use of SM for injecting dependencies.

A brief introduction to StructureMap

StructureMap is a DI/IOC tool exclusively for .NET programming. It helps in achieving looser coupling among classes and their dependencies, improve the testability of a class structure, and provide general flexibility mechanisms.

From StructureMap site

Consider using StructureMap if you:

  • Require significant extensibility
  • Simply want a generic configuration tool
  • Want to support multiple deployment configurations
  • Are using a Test-Driven Development philosophy or want to largely automate testing
  • Want to isolate a troublesome subsystem or provide smooth migration paths away from legacy interfaces
  • Need a great deal of configurable properties or plugin hot spots

Do not use StructureMap if an application or process requires a little flexibility. The abstraction and indirection afforded by StructureMap is unnecessary and even harmful in simpler systems or processes.

IOC implementation with StructureMap


Now let us see how to accomplish that using StructureMap. This is open source software available at:
http://sourceforge.net/projects/structuremap/. IOC is going to help you to unit test your code without a total implementation of your application.

You only need the DLL "StructureMap.dll" for this example. Add the reference to your project.

A simple implementation of StructureMap in our code copied from the StructureMap site.

In our example we always want any object that consumes "IClassB" to be given a concrete object of ClassB. To implement that, we need to add it to the ObjectFactory of StructureMap.

I am going to create a new static class that has a method to initialize the Object Factory as below:

    public static class ContainerBootstrapper
    { 
        public static void BootstrapStructureMap()
        { 
            // Initialize the static ObjectFactory container
 
            ObjectFactory.Initialize(x =>
            { 
          x.ForRequestedType<IClassB>().TheDefaultIsConcreteType<ClassB>(); 
            }); 
        } 
    }

Now our program class looks like this:

        static void Main(string[] args)
        {
            IClassA classA=new ClassA();//creating instance of class A
            ContainerBootstrapper.BootstrapStructureMap(); 
            var classB = StructureMap.ObjectFactory.GetInstance<IClassB>();
          
            //assign the instance to the classB property of class A
            classA.ClassB = classB; 

            //Call the method
            classA.DoSomethingFromClassB(); 
            Console.Read();
        }

Now we are going to experiment with it by configuring the structure map in the application configuration file.

Note: Most of the time while creating sections in configuration files we often end up with runtime errors due to missing a character in the name of a section or a misspelled assembly name. We often also do not suspect the errors happening in the application because of configuration mistakes. So, always care should be taken while changing the configuration files. I have many times seen the deployment team open a configuration file in Word and then it contained a special character.

My configuration changes

I have added a section for StructureMap and then added the relevant configuration. Note the term "PluginType" refers to the Interface class and "PluggedType" refers to the concrete class.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
      <
configSections>
<
section name="StructureMap"
type="StructureMap.Configuration.StructureMapConfigurationSection,StructureMap"/>
      </configSections>
 
      <
appSettings>
<
add key="MyClassObject" value="BusinessClasses.ClassB, BusinessClasses,
Version=1.0.0.0, Culture=neutral
"/>
      </appSettings
      <
StructureMap defaultAssembly="BusinessClasses">
            <DefaultInstance
                     PluginType  = "BusinessClasses.IClassB, BusinessClasses"
                     PluggedType = "BusinessClasses.ClassB, BusinessClasses"
                          />
      </
StructureMap>
</configuration>

Now I need to change the BootStructureMap() to incorporate the configurations settings to be active. There is a property called "PullConfigurationFromAppConfig" and we need to set it to true for ObjectFactory containers as below:

        public static void BootstrapStructureMap()
        { 
            // Initialize the static ObjectFactory container
 
            ObjectFactory.Initialize(x =>
            { 
                // x.ForRequestedType<IClassB>().TheDefaultIsConcreteType<ClassB>();
                x.PullConfigurationFromAppConfig = true
            }); 
        }

Now my Program class remains the same as we have handled the change in the class ContainerBootStrapper:

        static void Main(string[] args)
        {
            IClassA classA = new ClassA();//creating instance of class A
            ContainerBootstrapper.BootstrapStructureMap(); 
            var classB = StructureMap.ObjectFactory.GetInstance<IClassB>();
 
            //assign the instance to the classB property of class A
            classA.ClassB = classB;

            //Call the method
            classA.DoSomethingFromClassB(); 
            Console.Read(); 
        }

In this article, we have discussed using StructureMap for Dependency Injection. We will discuss implementing it with Unity Container by Microsoft in the next article.

X

Build smarter apps with Machine Learning, Bots, Cognitive Services - Start free.

Start Learning Now