Dependency injection is a fairly standard computer science topic nowadays, but I still see a lot of confusion over how dependency injection works within Episerver. In today's guide, I'm going to cover the tools Episerver give us developers out the box and cover some of their pro's and con's.

The ServiceLocator

The ServiceLocator can be thought of as a global container that provides a way to get Episerver dependencies in your code base. In the olden days of Episerver 6, you would have used the DataFactory (which implemented a singleton pattern) to get access to your Episerver data. The data factory pattern created pains if you ever wanted to unit test your code. You had all these concrete implementations dotted around your code base. In Episerver 7 onwards, we're provided with the ServiceLocator. The service locator allows us to work with the interface rather than implementations. This is a good start to making our website more unit testable. Our code now looks like this:
  var repository = ServiceLocator.Current.GetInstance<IContentRepository>();
  var contentReference = new ContentReference(1);

  return repository.Get<PageData>(contentReference);
Using interfaces and an injection pattern to access the Episerver API means we can now substitute the Episerver implementations with Mocks, which gives us a lot more power and control when we want to test Using the above code we could now run the below code to swap out the call to the Episerver database and use a mocked version instead.
  var serviceLocator = new Mock<IServiceLocator>();

  var mockRepository = new Mock<IContentRepository>();

  serviceLocator.Setup(x => x.GetInstance<IContentRepository>()).Returns(mockRepository.Object);
ServiceLocation is a big improvement from the old days.. but it has some limitations.

The Problems with Service Locator

Using the snippet of code above is all very good but in a project, you might have 100 files that need to call IContentRepository. Having this code duplicated also means you will need to write the same tedious set-up code in your unit tests everywhere. This is bad.


Episerver also provides an alternative way of injecting dependencies into your code, via Injected<>. Injected<> uses property injection via the IoC container to give you access to your dependencies. An example of how to use Injected<> can be seen below:
public class DummyExample
        internal Injected<IInterface> interface;

        public DummyExample()
            var implmentation = interface.Service;
Injected is really useful when you need to implement from things like ISelectionFactory or an InitializationModule. If you try to use constructor injection in these types of files, MVC will complain about not having a parameterless constructor.

Registering Your Own Code To Work With ServiceLocator

The last bit of the Episerver dependency injector toolkit is the [ServiceConfiguration] attribute. If you place [ServiceConfiguration] on top of a class, you can then use ServiceLocator or Injected<> to inject your own custom code. The code to do this would look like this:
[ServiceConfiguration(ServiceType = typeof(IInterface), Lifecycle = ServiceInstanceScope.HttpContext)]
public class DummyExample: IInterface
After you register your custom interface you can then use this code to get access to it:
  var customImplmentation = ServiceLocator.Current.GetInstance<IInterface>();
All these are really useful tools to have but, like most projects, the way you implement dependency injection is the things that will make or break your project. To learn a bit more about good practice patterns to be used within Episerver I would recommend reading EPiServer: Dependencies in Episerver Explained – Unit Testing Part 1