There are three aspects in choosing a DI approach with Sitecore 8.2:
The decision of which dependency injection container to use.
The way you integrate the container with Sitecore and ASP.NET MVC.
The pattern in which service dependencies and implementations are registered.
Picking a DI container
Sitecore 8.2 uses IServiceProvider / IServiceCollection as ...
The problem with the simple injector container is that they do not provide a conforming container option. They don't like it. So to replace it with Simple Injector requires a bit more effort.
In this post Habitat DI with Simple Injector - I explained how to use SI in a conforming way to register your dependencies for Habitat projects.
You could take a ...
In my experience, when you plan major changes in your solution, the worst thing you can do is apply all of them at once. When you inevitably run into problems, you won't know which of the changes caused them; that will make debugging and fixing so much harder.
Generally, the most reliable approach is to split your changes into as many small steps as ...
I'm not entirely sure there is a "recommended" approach - it mostly boils down to the container you'd like to use and the features you'd like to leverage from that container.
For instance, if you like non-conforming containers like Simple Injector and want to use the Verify() method on the container, then an approach like Rich's, in your third link, is a ...
Same instance for multiple services
I believe this can only be achieved with code registration:
var implementation = new ServiceImplementation();
serviceCollection.AddSingleton<IService>(provider => implementation);
serviceCollection.AddSingleton<IExtendedService>(provider => implementation);
In case ServiceImplementation has its own ...
The WFFM module was significantly re-written in version 8.1+ and allows configuration driven dependency injection out of the box.
For example, if you take a look at the /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions/Save Actions/Update Contact Details Save Action then you will see the following item definition:
Factory Object Name: /...
To inject something via constructor or get types with Service Locator you need to register your services first.
public class RegisterOoyalaServices : IocProcessor
public override void Process(IocArgs args)
One might think that there is already a similar question
on this matter. However, your exact question is a bit different.
An Upgrade Approach
As far as unwiring the existing DI containers (and updating Sitecore), I would start with trying to eliminate upgrade complications first.
1. Start with just removing your old DI completely.
While this may ...
When Sitecore gets reconfigured to use another container; will that container also be used to resolve these entries?
It depends on how that other container gets configured, exactly. If you use the approach of patching the <serviceProviderBuilder>, then the container gets replaced completely and there's only one DI implementation. This would be my ...
The reason you are getting No parameterless constructor error is because Sitecore cannot create an instance of your controller that takes parameters. Without dependency injection working correctly, Sitecore is looking for a controller that takes not inputs like this:
public ActionResult MyController()
What you do have is one that takes ...
Your configurator is run as a part of the DI container initialization. During that phase, you cannot use the Sitecore Factory, because, starting from Sitecore 8.2, Factory uses the DI container under the hood. This restriction is apparently there to prevent configuration loops: container requests something from the Factory, the Factory falls ...
I wrote a blog post on this here - here are the cliff notes.
I'm going to assume Sitecore 8.2 for the version here, but the process is pretty much the same for earlier versions too, there would be some small tweaks.
Registering your own IoC Container
If you want to use your own container with 8.2 instead of the Sitecore out of the box one, or if this is ...
I wanted to add this as the other answers are close, but not 100% IMO.
First - SitecoreContext and SitecoreService have overloaded constructors. So you have to use a factory registration to be able to resolve those. Otherwise you will be dependent the constructor that the container will select, if it is able to select one.
This is how I register the ...
Assuming you're running Sitecore 8.2 or later, you can add resolve="true" to the <pipeline> element to enable DI resolution for the processor.
Sitecore uses Microsoft.Extensions.DependencyInjection for dependency injection, which doesn't appear to list Windsor as a supported container. It may be possible, but I'd seriously consider whether Windsor ...
Ok - please don't use ServiceLocator to "fix" this issue. The problem looks to be because you have not registered your OoyalaController with your IoC container.
If you are using the standard Sitecore 8.2 container you can do this by creating a configurator for your project. You should also register your dependencies that the controller is requesting.
Is using a single, reused context a good approach?
Yes. It is the recommended approach.
Are there any pitfalls?
Yes. New documents added to your indexes will not show, until you re-open a new Search Context. So you may need to tie in your SearchContext to index update events.
Are there any good code examples of doing this, possibly with a dependency ...
Thanks to @Jeroen and @Mark for helping to lead me in the right direction.
Debugging locally, I found that the Assembly crawled in the AddMvcControllersInCurrentAssembly changes depending on optimization. Code below:
public static void AddMvcControllersInCurrentAssembly(this IServiceCollection serviceCollection)
Based on your comment above. You should move the definitions of those fields from the individual projects into a "Common" project in the Project Layer - you can then reference that in your individual Project Layer projects to keep the code as is.
Then you can put your computed field into the "Common" project.
It would only require a small refactor to do ...
Following the principles found in Helix, you should adhere to the Common Closure Principle:
Classes that change together are packaged together.
This means that you should define the computed index fields in the same place, as to where you define the fields on the Sitecore data templates - such that if the fields changes, your computed index should change ...
The simplest solution here seems to be to update your custom controller A.B.Controllers.AuthenticationController to have a unique name so that it doesn't conflict with the Sitecore one.
The risk of trying to change the Sitecore references to that controller are high and it would potentially make any future upgrades more complex as you would have to make ...
A central challenge in respect to Habitat/Helix is the modular architecture - each module is self-contained and does not know of the other modules (and possibly the underlying framework).
Kevin Brechbühl handles the modular architecture, but adds a reference to the container in all modules. This tight coupling breaks the Composition Root pattern as ...
G Killian, I posted a question here about using SimpleInjector which you might find useful also: SimpleInjector as default DI in Sitecore 8.2
It contains a reply from Richard for how you go about swapping out the default DI in Sitecore 8.2 for SimpleInjector which is our preferred framework for our project for a number of reasons but mostly as it's fast and ...
In 8.2; SOLR support comes out of the box. You can optionally add your preferred DI container, but are not required to do so.
The Sitecore Solr provider uses an IOC (Inversion of Control)
container so that all the elements inside it can be swapped without
re-compilation. The default Sitecore installation includes a default
implementation of the Solr ...
The default scope
With Microsoft DI, the Scoped lifetime will default to a request scope in ASP.NET.
Scoped lifetime services are created once per request.
Scoped objects are the same within a request, but different across ...
You should be able to register the two interfaces to the same singleton instance implementation, but only in code, not in config.
ServiceImplementation impl = new ServiceImplementation();
serviceCollection.AddSingleton<IService>(provider => impl);
serviceCollection.AddSingleton<IExtendedService>(provider => impl);
This kinda sucks because ...
We managed to identify the root cause of our memory leak. With help of MS and Sitecore, memory dump had lots of our controller and services hanging off of Root scope.
By design the sitecore disposes the objects on request end. Given that the controllers injected by Autofac were not compatible with Sitecore controllers, the objects didn't get disposed. As a ...
There are 2 parts to how the MS Di Abstractions and Container are working in Sitecore.
1: The Configuration
The config/configurators etc.. don't actually do the registration of the types with the container. Rather, they just add the required registrations into the IServiceCollection which at the basic level is just a collection. Nothing is done with that ...
When you add a computed index field to the configuration, the section uses a certain method to instantiate resulting .Net objects for each computed field type:
As we can see here, the method is the AddComputedIndexField function from the IDocumentBuilderOptions interface.
Depending on your configuration ...
While @dnstommy is correct, what you are doing is not best practice and you really should refactor if you can to use a pipeline approach. The answer to your question is in this line:
With that you are only registering MVC Controllers that live in the website project. Its hard to tell ...
Not knowing the details of your implementation on ICustomSitecoreContext, it looks to me like you are registering the dependencies incorrectly. While the ISitecoreContext needs the factory method to instantiate a new SitecoreContext - your other dependencies should be able to be created by the container.