具有Sitecore和WebApi控制器的SimpleInjector没有默认的构造函数

时间:2019-02-05 11:46:55

标签: c# asp.net-mvc asp.net-web-api sitecore simple-injector

我们已经在我们的4.4.x Helix项目中集成了SimpleInjector(Sitecore 8.2)。

我们的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 MVCWebApi都被使用(.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:类型'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的{​​{1}}中。

container的绑定重定向在根项目的WebApi中设置:

web.config

1 个答案:

答案 0 :(得分:1)

根据此answer并按照注释中的Steven所述,依赖解析器稍后会在Sitecore管道中被覆盖。

我已经扩展了git branch -d dev_4.0.4管道:

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>

在这里,我们在{em> Sitecore重置后为public class WebApiDependenceResolverProcessor { public void Process(PipelineArgs args) { // retrieve container here GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); } } 设置了依赖解析程序。