I frequently see Sitecore implementations that use no form of Dependency Injection (DI) or perhaps worse still lean on a Service Locator Pattern to build up component dependencies. When I tweeted about this situation some of the responses I got back really surprised me.
Wondering why more #sitecore web forms devs don’t use an IoC and employ DI. It’s 5 minutes work to get property injection going.
I’m not sure whether there is a lack of awareness about DI around some areas of the Sitecore developer community or, as some of the responses to the tweet suggested, we have more than our fair share of Dark Matter Developers.
In this post I’ll try to give the briefest overview of what DI is, and show just how simple it is to implement in a Sitecore solution.
What is Dependency Injection
Amazon’s summary text for Dependency Injection in .NET has this to say on Dependency Injection:
Dependency Injection is a great way to reduce tight coupling between software components. Instead of hard-coding dependencies, such as specifying a database driver, you inject a list of services that a component may need. The services are then connected by a third party. This technique enables you to better manage future changes and other complexity in your software.
In essence, stop creating explicit instances of components that you depend upon, instead pass that dependency in via a constructor parameter or a public property on your class. The business of creating this dependency is then no longer a concern of the class that you are writing. The fewer concerns that a piece of code has, the easier it will be to understand and maintain.
Take this one stage further and stop depending on concrete implementations and instead depend on an abstract definition of a service. In practical terms, take a dependency on an interface or abstract class that defines the behaviour that you require.
public YourClass(IDoSomethingService service)
public YourClass(ConcreteDoSomethingService service)
If you do nothing more than this you will already have reduced the class coupling in your application and started down the path of being able to unit test your code.
Setting up DI with Sitecore
Now we’ll see a very simple mechanism to get started with DI in a Sitecore implementation. The approach is based around Autofac which is one of many IoC containers available for the .NET framework.
Rather than repeat setup instructions from other sites the relevant instructions are linked to in the following simple steps that will get you going with DI:
- Install the ASP.NET WebForms integration for Autofac into your web application project.
You can do this manually by pulling down the code from the Autofac download page or simply use NuGet to install and configure the latest version of the integration package.
PM> Install-Package Autofac.Web
Here you are doing two things. Firstly, defining and exposing a container object that will be available throughout your web application. Then populating that container with instructions on how to create objects used by your web application.
In order to inject dependencies into Sitecore sublayouts you will need to expose their dependencies as public properties that have a public setter. The Autofac WebForms integration works by employing a PropertyInjectionModule which will populate those properties for you.
Make sure that you have registered the types that you wish to be injected in your application start event handler, for example:
builder.Register<IService>(c => new ConcreteServiceImplementation());
It really is that simple to get up and running with an IoC container and start using Dependency Injection in your implementations. Take a look at the sample code gist for more details..
Excellent article, very useful. Do you know if there is an easy way to get DI on a class that is defined in a Sitecore event?
I’ve been googling around a bit before (one of the results was this blog ;)):
+1 for that blog post.
Today the official mechanism is via Sitecore.Configuration.Factory.CreateObject() , you can read more about this in these links:
IoC container support is being added into the Sitecore MVC offering, see http://sitecorecommunitydocs.uservoice.com/forums/286986-sitecore-mvc/suggestions/7321940-dependency-injection for updates.
Nice little article – wouldn’t RECOMMEND overriding global in Sitecore solutions any more (especially going into 8). I used to do it, but have started to use other means. WebActivator would be a popular alternative or self initialising singleton or *something* (still don’t have a model I am 100% happy with)
Thanks. Completely agree with the WebActivator choice.
Pingback: Dependency injection and Inversion of Control (IOC) | Jamie Little
Sitecore is looking at adding Dependency Injection into their MVC offering. The details are here.