Dependency injection (DI) is a technique for achieving loose coupling between objects and their collaborators, or dependencies. Without dependency injection, a class must directly instantiate collaborator or use static references. With dependency injection, the objects a class need are provided for it.
Most often, classes will declare their dependencies through their constructor. Sitecore only supports this approach, known as constructor injection.
The Sitecore implementation of DI is based on the Microsoft.Extensions.DependencyInjection abstractions from ASP.NET Core.
You can register the abstraction either in configuration or with code.
Registration in configuration
You can configure abstraction in the services node in any Sitecore include config file. For example:
<register serviceType="IMyService, MyAbstraction.Assembly" implementationType="MyServiceImplementation, MyImplementation.Assembly" />
<register serviceType="MyServiceBase, MyAbstraction.Assembly" implementationType="MyServiceBaseImplementation, MyImplementation.Assembly" />
Registration in code
You use the
IServicesConfigurator interface to configure services from code. For example:
- Implement the
public class MyServicesConfigurator : IServicesConfigurator
public void Configure(IServiceCollection serviceCollection)
There is more information about IServiceServiceCollection on the MSDN website.
- Register the configurator:
<configurator type= "MyServicesConfigurator, MyAssembly"/>
Read important information about Service Lifetimes and Registration Options on the MSDN website.
To support scoped per request lifetime,
Sitecore.DependencyInjection.SitecorePerRequestScopeModule, Sitecore.Kernel was added to the http modules. If the module is disabled, Scoped has the same behavior as Singleton.
This section describes how you resolve (locate) a registered service through DI, using a service locator.
Injection to types created by Factory
You must use the
resolve attribute. The following changes enable injection for the ShowReason processor of the
<processor type="Sitecore.Pipelines.Shutdown.ShowReason, Sitecore.Kernel" resolve="true"/> </shutdown>
Injection and MVC
To use dependency injection in an MVC controller, add this processor to the pipeline:
<processor type="Sitecore.Mvc.Pipelines.Loader.InitializeDependencyResolver, Sitecore.Mvc"/>
Injection to WebForms and UserControls
[Sitecore.DependencyInjection.AllowDependecyInjection] attribute for Forms and UserControls:
public partial class Default : System.Web.UI.Page
protected Default() // important
public Default(IMyService myService, MyServiceBase serviceBase)
The Form must also have a default constructor (this is a limitation of ASP.NET).
public partial class DefaultControl : System.Web.UI.UserControl
protected DefaultControl() // important
public DefaultControl(IMyService myService, MyServiceBase serviceBase)
It is currently not possible to use dependency injection with all parts of Sitecore, so sometimes the service locator is the only solution. This is, for example, the case in page handler factories, MVC controller factories, and in static manager for backward compatibility.
Therefore, you can use the
Sitecore.DependencyInjection.ServiceLocator class. For example:
var service = ServiceLocator.ServiceProvider.GetService(typeof(IMyService))
Or, for example:
var service = ServiceLocator.ServiceProvider.GetService<MyServiceBase>();
View the dependency injection configuration
You can see the details of the dependency injection at this URL: http://[instance]/sitecore/admin/showservicesconfig.aspx.
You can see configured-in services (node services) at this URL: http://[instance]/sitecore/admin/showconfig.aspx.
Replace service provider
You can replace the service provider. Sitecore uses the Microsoft.Extensions.DependencyInjection package default.
To replace default provider:
- Inherit from
Sitecore.DependencyInjection.BaseServiceProviderBuilderand implement the
public class MyProviderBuilder : BaseServiceProviderBuilder
protected override IServiceProvider BuildServiceProvider(IServiceCollection serviceCollection)
The Framework site has a list of the containers that Sitecore supports.
- Replace the default builder in
Sitecore.configwith your builder:
<serviceProviderBuilder type="Sitecore.DependencyInjection.DefaultServiceProviderBuilder, Sitecore.Kernel"/>
You can also patch this node with an include file: