Мы интегрировали SimpleInjector (4.4.x) в наш проект Sitecore 8.2спираль.
У нас есть проект Dependency Injection в нашем Базовый слой, который состоит из следующего конвейера:
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: An error occurred when trying to create a controller of type 'HelloController'. Make sure that the controller has a parameterless public constructor.
Трассировки стека:
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
Внутреннее исключение:
System.ArgumentException: Type 'Company.Feature.Example.HelloController' does not have a default constructor
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 Registrationscontainer.
Также перенаправления привязки для 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>
Привет, @Steven, твое время как раз в тот момент, когда я наткнулся на это: sitecore.stackexchange.com/questions/1739/… Действительно, позже в конвейере Sitecore объект GlobalConfiguration переопределяется. Я применил патч, и теперь он работает.





В соответствии с этим отвечать и как предложено в комментарии Стивен, преобразователь зависимостей переопределяется позже в конвейере 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 сбрасывает его.
Что я вижу из сведений об исключении, так это то, что по какой-то причине (это мне неясно)
SimpleInjectorWebApiDependencyResolverне используетсяDefaultHttpControllerActivator, потому чтоSimpleInjector.Integration.WebApi.SimpleInjectorWebApiDependencyResolverникогда не вернетnull, когдаIHttpControllerзапрашивает производноеDefaultHttpControllerActivator. Возможно, позжеGlobalConfiguration.Configuration.DependencyResolverснова будет переопределен. Вам придется отладить это, чтобы выяснить, почему это происходит.