带有 Sitecore 和 WebApi 控制器的 SimpleInjector 没有默认构造函数
SimpleInjector with Sitecore and WebApi controller does not have a default constructor
我们在 Sitecore 8.2
Helix 项目中集成了 SimpleInjector (4.4.x
)。
我们的 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);
}
也如 this post 中所述,流水线处理器在 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
注册在 container
.
的 Root Registrations
中
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>
根据评论中建议的 answer and as Steven,依赖项解析器稍后会在 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重置它之后。
我们在 Sitecore 8.2
Helix 项目中集成了 SimpleInjector (4.4.x
)。
我们的 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);
}
也如 this post 中所述,流水线处理器在 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
注册在 container
.
Root Registrations
中
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>
根据评论中建议的 answer and as Steven,依赖项解析器稍后会在 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重置它之后。