---
title: Dependency injection
slug: cms-11/dev-docs/dependency-injection
docTags: 
createdAt: 2026-07-22T19:45:22.664Z
---

Optimizely Customized Commerce defines dependency injection in an abstract API in the  `EPiServer.ServiceLocation`  namespace within the `EPiServer.Framework` package. There is an implementation of the abstraction based on `StructureMap` in package `EPiServer.ServiceLocation.StructureMap`. You can use `StructureMap` directly or use Optimizely's `StructureMap` abstractions when configuring the IOC container. The recommended approach is to use the abstractions documented in this topic.

## Implicit registration of services

Below are examples of using implicit registration. To accomplish this, use the `ServiceConfiguration` attribute to make it easier to read classes because it registers the same class as the implementation. The following example registers a service as a transient service (instances are created every time) or a singleton service (a single instance is re-used).

```csharp
public interface IService {
  void Sample();
}
[ServiceConfiguration(ServiceType = typeof (IService))]
public class TransientService: IService {
    public void Sample() {
      throw new NotImplementedException();
    }
  }
  [ServiceConfiguration(ServiceType = typeof (IService), Lifecycle = ServiceInstanceScope.Singleton)]
public class SingletonService: IService {
  public void Sample() {
    throw new NotImplementedException();
  }
}
```

## Explicit registration of services

The code below provides examples of registering `IService` and its implementation service using the CMS abstractions. The abstractions are available in initialization modules which implement the `IConfigurableModule` interface. Inline comments describe the examples in more detail:

```csharp
[InitializableModule]
public class ModuleWithServices: IConfigurableModule {
  public void ConfigureContainer(ServiceConfigurationContext context) {
    //Register IService1 with implementation Service1, create new instance every time
    context.Services.AddTransient<IService, Service>();
    //Register IService1 with implementation Service1, re-use a single instance
    context.Services.AddSingleton<IService, Service>();
    //Register IService1 with custom factory
    context.Services.AddTransient<IService>((locator) => new Service());
    //Register IService1 to be cached per HTTP request or per thread if no HTTP request exist
    context.Services.AddHttpContextOrThreadScoped<IService, Service>();
  }
  public void Initialize(InitializationEngine context) {}
  public void Uninitialize(InitializationEngine context) {}
}
```

## Use StructureMap configuration

If the package `EPiServer.ServiceLocation.StructureMap` is used as dependency injection implementation, you can configure the IOC container using the `StructureMap` API instead of the CMS API. The recommendation is to use the CMS API, unless some specific `StructureMap` feature not exposed in Episerver API is used. That way it is easier to replace `StructureMap` with another IOC implementation in the future if that need occurs. To use direct `StructureMap` configuration, use the `StructureMap` extension method, which returns an instance of `StructureMap.IContainer`. Then, the configuration can be done directly against `StructureMap`.

```csharp
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.ServiceLocation.Compatibility;
namespace EPiServerSamples {
  [InitializableModule]
  public class ModuleWithServices: IConfigurableModule {
    public void ConfigureContainer(ServiceConfigurationContext context) {
      //Use extension method StructureMap() to access StructureMap.IContainer
      context.StructureMap().Configure(c => {
        c.For().Use();
      });

    }
    public void Initialize(InitializationEngine context) {}
    public void Uninitialize(InitializationEngine context) {}
  }
}
```

## ServiceLocator

To get an instance of a service without using dependency injection, use the `ServiceLocator` class and its `Current` property. Example:

```csharp
var myService = ServiceLocator.Current.GetInstance<IService>();
```

## Intercept existing services

There are occasions when it is useful to intercept calls to a service, for example, to debug or to add logging. By using the `IServiceConfigurationProvider.Intercept<T>` method, you can replace existing services with another implementation. The provided factory method will have access to the default instance of the service.

If you register several implementations for a service, it intercepts all registrations. The interceptor service has the same scope as the registered intercepted service.

The following example shows an interceptor registration of the `ISynchronizedObjectInstanceCache` where the interceptor logs remote removals.

```csharp
using EPiServer.Framework;
using EPiServer.Framework.Cache;
using EPiServer.Framework.Initialization;
using EPiServer.Logging;
using EPiServer.ServiceLocation;
using System;

namespace EPiServerSamples {
  [ModuleDependency(typeof (EPiServer.Web.InitializationModule))]
  public class LoggingInitializer: IConfigurableModule {
    public void ConfigureContainer(ServiceConfigurationContext context) {
      context.Services.Intercept<ISynchronizedObjectInstanceCache>(
        (locator, defaultCache) => new LoggingSynchronizedCache(defaultCache));
    }
    public void Initialize(InitializationEngine context) {}
    public void Uninitialize(InitializationEngine context) {}
  }
  public class LoggingSynchronizedCache: ISynchronizedObjectInstanceCache {
    private readonly ISynchronizedObjectInstanceCache _defaultCache;
    private readonly ILogger _log = LogManager.GetLogger(typeof (LoggingSynchronizedCache));

    public LoggingSynchronizedCache(ISynchronizedObjectInstanceCache defaultCache) {
      _defaultCache = defaultCache;
    }
    public void RemoveRemote(string key) {
      if (_log.IsDebugEnabled())
        _log.Debug($"Remote removal called at '{DateTime.Now}' with key '{key}'");

      _defaultCache.RemoveRemote(key);
    }
    public IObjectInstanceCache ObjectInstanceCache => _defaultCache.ObjectInstanceCache;
    public FailureRecoveryAction SynchronizationFailedStrategy {
      get {
        return _defaultCache.SynchronizationFailedStrategy;
      }
      set {
        _defaultCache.SynchronizationFailedStrategy = value;
      }
    }
    public object Get(string key) => _defaultCache.Get(key);
    public void Insert(string key, object value, CacheEvictionPolicy evictionPolicy) => _defaultCache.Insert(key, value, evictionPolicy);
    public void Remove(string key) => _defaultCache.Remove(key);
    public void RemoveLocal(string key) => _defaultCache.RemoveLocal(key);
  }
}
```

## Integrate with MVC 5 dependency resolver

Templates developed on CMS can set `IServiceLocator` to resolve dependencies in controllers in MVC 5. The following code provides an example of integrating `IServiceLocator`. The Alloy sample templates use this sample.

```csharp
[InitializableModule]
[ModuleDependency(typeof (EPiServer.Web.InitializationModule))]
public class DependencyResolverInitialization: IConfigurableModule {
  public void ConfigureContainer(ServiceConfigurationContext context) {}
  public void Initialize(InitializationEngine context) {
    DependencyResolver.SetResolver(new ServiceLocatorDependencyResolver(context.Locate.Advanced));
  }
  public void Uninitialize(InitializationEngine context) {}
  public void Preload(string[] parameters) {}
}

public class ServiceLocatorDependencyResolver: IDependencyResolver {
  readonly IServiceLocator _serviceLocator;

  public ServiceLocatorDependencyResolver(IServiceLocator serviceLocator) {
    _serviceLocator = serviceLocator;
  }

  public object GetService(Type serviceType) {
    if (serviceType.IsInterface || serviceType.IsAbstract) {
      return GetInterfaceService(serviceType);
    }
    return GetConcreteService(serviceType);
  }

  private object GetConcreteService(Type serviceType) {
    try {
      // Can't use TryGetInstance here because it won’t create concrete types
      return _serviceLocator.GetInstance(serviceType);
    } catch (ActivationException) {
      return null;
    }
  }

  private object GetInterfaceService(Type serviceType) {
    object instance;
    return _serviceLocator.TryGetExistingInstance(serviceType, out instance) ? instance : null;
  }

  public IEnumerable<object> GetServices(Type serviceType) {
    return _serviceLocator.GetAllInstances(serviceType).Cast<object>();
  }
}
```
