Thursday, June 6, 2013

IoC (Inversion of Control) in SharePoint Projects

According to Wikipedia “Inversion of Control (IoC) is a programming technique, in which object coupling is bound at run time by an assembler object and is typically not known at compile time.
It is basically, abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming.
Inversion of control is sometimes facetiously referred as the "Hollywood Principle: Don't call us, we'll call you"

One of the ways to achieve IoC is Dependency Injection.
Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time. It injects the depended-on element (object or value etc) to the destination automatically by knowing the requirement of the destination.
In simple terms, Dependency injection means giving an object its instance variables.

Two most common ways to achieve Dependency Injection are:
  1. Constructor Injection, in which the dependencies are provided through the constructor.
  2. Setter Injection (Property Injection), in which the dependencies are set onto public properties exposed by the object in need.


In Dependency Injection each component must declare a list of dependencies required to perform its task. At runtime, an IoC Container performs binding between these components.
Some other benefits of Inversion of control are as follows:
  • There is a decoupling of the execution of a certain task from implementation
  • Every module can focus on what it is designed for
  • Modules make no assumptions about what other systems do but rely on their contracts
  • Replacing modules has no side effect on other modules


Well, Inversion of Control is all about getting freedom, more flexibility, and less dependency.
So now, we have understood how good it is to use IoC while building enterprise level applications. Now being SharePoint developer, I was wondering how I use it in SharePoint Projects. Let's explore!!

Here, I have used StructureMap as IoC container to inject my dependency to SharePoint.

Before we begin, we need to know where we can inject objects. In an MVC or WebForms app, I’d just add code to the appropriate place in Global.asax.cs, but in the territory of SharePoint, it is different case. We have to do some dark magic and that’s where HttpModule comes in picture.
So the first step is, add class called “ContainerBootstrapper” and add static method in it called, “Bootstrap()” as follow:


public class ContainerBootstrapper
{
    public static void Bootstrap()
    {
        ObjectFactory.Initialize(x =>
        {
            x.For<IMyRepository>().Use<MyRepository>()
                .Ctor<string>("cArg").Is("Constructor Argument Value");
            x.For<IMyService>().Use<MyService>();
        });
    }
}


Now, it’s time to add HttpModule to your project.
Open HttpModule and in Init() Method, just call your function to initialize container.

public void Init(HttpApplication context)
{
    InitializeContainer();
}


The InitializeContainer() function goes as follows:

private void InitializeContainer()
{
    ContainerBootstrapper.Bootstrap();

}

Well, HttpModule can be called multiple times during application lifetime (a bad thing), so we need to protect our container from being re-initialized. So let’s add a condition with static variable “_HasAlreadyInitialized” and set it to true once we initialize our dependencies. We also need to lock the method so other processes can’t access at the time of initialization. After all these consideration, our InitializeContainer () function will go as follows:

private void InitializeContainer()
{
    if (!_HasAlreadyInitialized)
    {
        lock (_InitProcess)
        {
            ContainerBootstrapper.Bootstrap();
            _HasAlreadyInitialized = true;
        }
    }

}

The complete class code will be as follows:

public class BootstrapInitializer : IHttpModule
{
    private static bool _HasAlreadyInitialized = false;
    private readonly static object _InitProcess = new object();

    /// <summary>
    /// You will need to configure this module in the web.config file
    /// of your web and register it with IIS before being able to use it.
    /// For more information see the following link:
    /// http://go.microsoft.com/?linkid=8101007

    /// </summary>
    #region IHttpModule Members

    public void Dispose()
    {
        //clean-up code here.
    }

    public void Init(HttpApplication context)
    {
        InitializeContainer();
    }

    #endregion

    #region Custom Methods

    private void InitializeContainer()
    {
        if (!_HasAlreadyInitialized)
        {
            lock (_InitProcess)
            {
                ContainerBootstrapper.Bootstrap();
                _HasAlreadyInitialized = true;
            }
        }
    }

    #endregion

}

That’s all!!
I hope you guys have enjoyed the new flavor of SharePoint Soup!!

2 comments:

  1. This is really cool and so useful. Thanks!

    ReplyDelete
  2. Really nice post Dipesh! Very detailed and informative. Keep on writing...

    ReplyDelete