dependency-injectionsitecoreautofacsitecore8sitecore8.2

Sitecore 8.2 Autofac Dependency Injection Error Clarification


I'm getting an error below when trying to use the Autofac DI with Sitecore 8.2:

The dependency resolver is of type 'Sitecore.Mvc.Controllers.SitecoreDependencyResolver' but was expected to be of type 'Autofac.Integration.Mvc.AutofacDependencyResolver'. It also does not appear to be wrapped using DynamicProxy from the Castle Project. This issue could be the result of a change in the DynamicProxy implementation or the use of a different proxy library to wrap the dependency resolver.

Any idea on:

  1. Why such scenarios occurs?
  2. What does above mean?
  3. How to fix?

Solution

  • Root of the issue

    This happens because AutofacDependencyResolver is not MVC's current dependency resolver. Here's the description of how AutofacDependencyResolver.Current attempts to locate the current instance of itself:

    http://docs.autofac.org/en/latest/integration/mvc.html#using-the-current-autofac-dependencyresolver

    So you need to set up AutofacDependencyResolver with MVC. Normally, you would just follow this guide:

    http://docs.autofac.org/en/latest/integration/mvc.html#quick-start

    Although, that is what you are probably doing already. The problem is, at some point Sitecore will override the configured dependency resolver with its own, and that happens after Application_Start is executed. So AutofacDependencyResolver ends up not being used by MVC.

    How to fix

    Follow this guide:

    http://www.seanholmesby.com/safe-dependency-injection-for-mvc-and-webapi-within-sitecore/

    The essence of it is that you'll need to create a custom dependency resolver which will use AutofacDependencyResolver first, and if a dependency is not found, it'll fall back to SitecoreDependencyResolver.

    The dependency resolver should be configured as a processor in Sitecore's initialize pipeline, which will make sure that Sitecore's dependency resolver is already available.

    You can find Autofac-specific examples in this GitHub repository:

    https://github.com/HedgehogDevelopment/sitecore-chained-dependency-resolver/tree/master/InversionOfControl.Autofac

    Overriding Autofac's dependency resolver accessor

    If the above doesn't help, you can tell Autofac how to get the current resolver.

    When you create the Autofac resolver, save that object in a variable, and once you register the chained resolver in MVC, use the method AutofacDependencyResolver.SetAutofacDependencyResolverAccessor():

    var autofacResolver = new AutofacDependencyResolver(container);
    
    IDependencyResolver chainedMvcResolver = new ChainedMvcResolver(
        autofacResolver,
        DependencyResolver.Current);
    
    DependencyResolver.SetResolver(chainedMvcResolver);
    
    AutofacDependencyResolver.SetAutofacDependencyResolverAccessor(() => autofacResolver);
    

    Now Autofac won't try to look for its own resolver directly in DependencyResolver.Current or Castle's DynamicProxy. It will directly use the resolver object you provided.