The reason of that is the default Simple Injector implementation regarding constructor resolution behavior. Lots of Sitecore classes like Controllers implemented the way that they have multiple constructors.

Out of the box, Simple Injector only allows the creation of classes that contain a single public constructor. They explain this as having multiple constructors is an anti-pattern and I agree.

While creating a container and registering types in it I usually register MVC controllers as well to be able to inject dependencies into them by setting the resolver to the default MVC DependencyResolver class.
This means that Sitecore controllers within my solution now are being instantiated by IoC container. When any of them have multiple constructors the Simple Injector throws exception as it can’t instantiate those.

It was quite confusing situation when I installed few Sitecore modules and they just didn’t work as expected and took a while to figure out.

Fortunately there is a solution for that. We can implement a custom constrctor resolution behavior. There are more ways to do that but here is what I use. This class will try to find the most resolvable constructor in the class that is being instantiated. If anything wrong it will just fallback to default “single constructor behavior”.

using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using SimpleInjector;
using SimpleInjector.Advanced;
public class MostResolvableConstructorBehavior : IConstructorResolutionBehavior
{
	private readonly Container container;
	private readonly IConstructorResolutionBehavior fallbackBehavior;
	public MostResolvableConstructorBehavior(Container container)
	{
		this.container = container;
		this.fallbackBehavior = container.Options.ConstructorResolutionBehavior;
	}
	private bool IsCalledDuringRegistrationPhase
	{
		get { return !this.container.IsLocked(); }
	}
	public ConstructorInfo GetConstructor(Type service, Type implementation)
	{
		var constructors = implementation.GetConstructors();
		if (!constructors.Any())
		{
			return this.fallbackBehavior.GetConstructor(service, implementation);
		}
		return constructors.Select(ctor => new { ctor, parameters = ctor.GetParameters() })
				.Where(type => this.IsCalledDuringRegistrationPhase
					|| constructors.Length == 1
					|| type.parameters.All(p => this.CanBeResolved(p, service, implementation)))
				.OrderByDescending(type => type.parameters.Length)
				.Select(type => type.ctor)
			.First();
	}
	private bool CanBeResolved(ParameterInfo p, Type service, Type implementation)
	{
		return this.container.GetRegistration(p.ParameterType) != null || this.CanBuildType(p, service, implementation);
	}
	private bool CanBuildType(ParameterInfo p, Type service, Type implementation)
	{
		try
		{
			this.container.Options.DependencyInjectionBehavior.BuildExpression(new InjectionConsumerInfo(service, implementation, p));
			return true;
		}
		catch (ActivationException)
		{
			return false;
		}
	}
}

And now we just need to do this while initializing the container:

container.Options.ConstructorResolutionBehavior = new MostResolvableConstructorBehavior(container);

So my initializer class looks like this:

using System.Web.Mvc;
using SimpleInjector;
using SimpleInjector.Integration.Web.Mvc;
using Sitecore.Pipelines;
namespace Website
{
	public class DependencyInjectionInitializer
	{
		public void Process(PipelineArgs args)
		{
			Initialize();
		}
		public static void Initialize()
		{
			var container = new Container();
			// Change the consturctor resolution behavior here
			container.Options.ConstructorResolutionBehavior = new MostResolvableConstructorBehavior(container);
			// Register all solution related types
			RegisterWebsiteTypes(container);
			container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
			container.RegisterMvcIntegratedFilterProvider();
			// Register the container as MVC IDependencyResolver.
			DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
        }
		private static void RegisterWebsiteTypes(Container container)
	    {
            // container.Register<ISitecoreContext, SitecoreContext>(Lifestyle.Transient);
			// ...
		}
	}
}

If that’s unclear, I initialize the container in the ‘initialize’ Sitecore pipeline by having next config:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor type="Website.DependencyInjectionInitializer, Website" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

This solution works for me now, all modules came back to normal working, but still need to test that more lol 🙂

Hope it was helpful 🙂

Share article
See also

MVC renderings with xWrap framework – Sitecore Experience Wrapper

Read more Volodymyr Hil 10.12.2018

Introducing xWrap framework – Sitecore Experience Wrapper

Read more Volodymyr Hil 09.12.2018

A recap from Sitecore Symposium 2018 and MVP summit

Read more Volodymyr Hil 25.10.2018

Using the service bus to transfer messages between instance roles

Read more Volodymyr Hil 10.06.2018

Using Swagger in Sitecore solution as a helix feature

Read more Volodymyr Hil 19.02.2018