SimpleInjector с Sitecore и контроллером WebApi не имеет конструктора по умолчанию - PullRequest
0 голосов
/ 05 февраля 2019

Мы интегрировали SimpleInjector (4.4.x) в наш Sitecore 8.2 Helix проект.

У нас есть проект внедрения зависимостей в нашем Foundation Layer , которыйсостоит из следующего конвейера:

public void Process(PipelineArgs args)
{
    var container = new Container();
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

    // register app dependencies (omitted for readability)

    // get assemblies of our application
    container.RegisterMvcControllers(assemblies);
    container.RegisterWebApiControllers(GlobalConfiguration.Configuration,assemblies);

    container.Verify();

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    GlobalConfiguration.Configuration.DependencyResolver =
        new SimpleInjectorWebApiDependencyResolver(container);
}

Также, как описано в этого поста , конвейерный процессор реализован в конвейере Sitecore initialize:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initializeDependencyInjection/>
      <initialize>
        <processor type="Company.Foundation.Example.DependencyInjectionProcessor, Company.Foundation.Example"
                   patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory, Sitecore.Mvc']" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

Как видите, используются ASP.NET MVC и WebApi (.NET 4.6).Наше решение состоит только из контроллеров MVC.То, что мы пытаемся достичь, - это ввести WebApi в наше решение.При добавлении следующего контроллера все работает хорошо:

public class HelloController : ApiController
{
    [HttpGet, Route("api/hello")]
    public IHttpActionResult Get()
    {
        return Ok("Hello World!");
    }
}

Но когда я добавляю зависимость (и также регистрирую), например:

public interface IFoo
{
    string Hello { get; }
}

public class Foo : IFoo
{
    public string Hello => "Hello World!";
}

public class HelloController : ApiController
{
    private readonly IFoo _foo;

    public HelloController(IFoo foo)
    {
        _foo = foo;
    }

    [HttpGet, Route("api/hello")]
    public IHttpActionResult Get()
    {
        return Ok(_foo.Hello);
    }
}

Я получаю следующее сообщение об исключении ввремя выполнения при выполнении HTTP-запроса:

System.InvalidOperationException: произошла ошибка при попытке создать контроллер типа «HelloController».Убедитесь, что контроллер имеет открытый конструктор без параметров.

Трассировка стека:

at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()

InnerException:

System.ArgumentException: Type 'Company.Feature.Example.HelloController 'не имеет конструктора по умолчанию

at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

Меня удивляет то, что container.Verify() не выдает никаких исключений или предупреждений.При отладке я вижу, что HelloController зарегистрирован в Root Registrations container.

Также перенаправления привязки для WebApi установлены в web.config корневого проекта:

<dependentAssembly>
  <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" xmlns="urn:schemas-microsoft-com:asm.v1" />
  <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" xmlns="urn:schemas-microsoft-com:asm.v1" />
</dependentAssembly>

1 Ответ

0 голосов
/ 07 февраля 2019

Согласно этому ответу и, как Стивен , предложенный в комментарии, преобразователь зависимостей переопределяется позже в конвейере Sitecore.

Я расширил initialize конвейер:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initializeDependencyInjection/>
      <initialize>
        <processor type="Company.Foundation.Example.DependencyInjectionProcessor, Company.Foundation.Example"
                   patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory, Sitecore.Mvc']" />
        <processor type=" Company.Foundation.Example.WebApiDependenceResolverProcessor, Company.Foundation.Example"
                   patch:after="*[@type='Sitecore.PathAnalyzer.Services.Pipelines.Initialize.WebApiInitializer, Sitecore.PathAnalyzer.Services']" />
      </initialize>
    </pipelines>
  </sitecore>
</configuration>

Куда я также добавил следующий процессор:

public class WebApiDependenceResolverProcessor
{
    public void Process(PipelineArgs args)
    {
        // retrieve container here

        GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
    }
}

Здесь мы устанавливаем преобразователь зависимостей для WebApi после Sitecoreсбрасывает его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...