NInject v3.3.4和WebApi 2,无参数构造函数

时间:2019-04-15 21:21:51

标签: c# asp.net-web-api ninject

请使用NInject和Web API 2帮助我摆脱困境。我有一个WebApi项目。我安装了Ninject.Web.WebApi.WebHost v3.3.0 Nuget。这带来了

  • Ninject.Web.WebApi.WebHost v3.3.0
  • Ninject.Web.WebApi v3.3.0
  • Ninject.Web.Common.WebHost v3.3.1
  • Ninject.Web.Common v3.3.1
  • Ninject v3.3.4

其中一个已在App_Start文件夹中生成了Ninject.Web.Common.cs。我为它的图形修改了RegisterServices方法:

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Load<SubscriptionApiModule>();
    }

正在加载的模块包含IQuerySubscription的绑定:

    namespace SubscriptionApi.Models
    {
    ...
        public class SubscriptionApiModule : NinjectModule
        {
            public override void Load()
            {
                Bind<IQuerySubscription>().To<QueryMultipubForSubscription>();
                ...
            }
        }
    }

我对SubscriptionApiModule的配置非常有信心。我有单元测试,提供带有SubscriptionApiModule的StandardKernel将响应.Get请求与我期望的具体类的证据。

我有几个控制器。这是一个:

[RoutePrefix("api/SubscriptionCheck")]
public class SubscriptionCheckController : ApiController
{
    public SubscriptionCheckController(IQuerySubscription queryService)
    {
        QueryService = queryService;
    }

    private IQuerySubscription QueryService { get; }

    [HttpGet]
    [Route("Heartbeat")]
    public string Heartbeat()
    {
        return "thump";
    }

    [HttpGet] 
    [Route("Get/{email}/{productCode}")]
    [EnableCors(origins: "*", headers: "*", methods:"*")]
    public async Task<bool> Get(string email, string productCode)
    {
        return await QueryService.IsSubscribed(email, productCode);
    }
}

我添加了心跳诊断。我运行API,并在浏览器地址中输入http://localhost:xxxxx/api/SubscriptionCheck/Heartbeat,并显示以下响应:

<Error>
    <Message>An error has occurred.</Message>
    <ExceptionMessage>
        An error occurred when trying to create a controller of type 'SubscriptionCheckController'. Make sure that the controller has a parameterless public constructor.
    </ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace>
        at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()
        </StackTrace>
        <InnerException>
            <Message>An error has occurred.</Message>
            <ExceptionMessage>
                Type 'SubscriptionApi.Controllers.SubscriptionCheckController' does not have a default constructor
            </ExceptionMessage>
            <ExceptionType>System.ArgumentException</ExceptionType>
            <StackTrace>
                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)
            </StackTrace>
        </InnerException>
</Error>

显然,该容器尚未向Web Api 2框架注册。有时,我曾经使用过一种老旧的工具。在CreateKernel方法中,在RegisterServices(kernel)之后:

GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

这使我在启动时遇到了异常:

  

Ninject.ActivationException    HResult = 0x80131500    消息=使用从ModelValidatorProvider到NinjectDefaultModelValidatorProvider的绑定激活ModelValidatorProvider时出错   在两个服务的构造函数之间检测到周期性依赖关系。

     

激活路径:    3)将依赖项ModelValidatorProvider注入到DefaultModelValidatorProviders类型的构造函数的参数defaultModelValidatorProviders中    2)将依赖项DefaultModelValidatorProviders注入到NinjectDefaultModelValidatorProvider类型的构造函数的参数defaultModelValidatorProviders中    1)请求ModelValidatorProvider

     

建议:    1)确保您没有声明该服务的任何实现上的ModelValidatorProvider依赖项。    2)考虑将服务合并为一个,以消除周期。    3)使用属性注入代替构造函数注入,并实现IInitializable       如果需要在插入属性值后运行初始化逻辑。

     

来源=    堆栈跟踪:   

为此,我尝试了在某处读到的骇客。我在对RegisterServices的调用下,并在分配给.DependencyResolver之前,将其添加到CreateKernel中:

            System.Collections.Generic.IEnumerable<object> configuredObjects =
                GlobalConfiguration.Configuration.Services.GetServices(
                    typeof(System.Web.Http.Validation.ModelValidatorProvider));
            System.Collections.Generic.IEnumerable<System.Web.Http.Validation.ModelValidatorProvider> configuredProviders =
                configuredObjects.Cast<System.Web.Http.Validation.ModelValidatorProvider>();
            Ninject.Web.WebApi.Filter.DefaultModelValidatorProviders defaultProviders =
                new Ninject.Web.WebApi.Filter.DefaultModelValidatorProviders(configuredProviders);
            kernel
                .Bind<Ninject.Web.WebApi.Filter.DefaultModelValidatorProviders>()
                .ToConstant(defaultProviders);

这给了我一个例外:

  

Ninject.ActivationException     HResult = 0x80131500     消息=激活DefaultModelValidatorProviders时出错   可以使用多个匹配的绑定。   匹配绑定:     1)从DefaultModelValidatorProviders绑定到常量值     2)从DefaultModelValidatorProviders绑定到常量值   激活路径:     2)将依赖项DefaultModelValidatorProviders注入到NinjectDefaultModelValidatorProvider类型的构造函数的参数defaultModelValidatorProviders中     1)请求ModelValidatorProvider

     

建议:     1)确保只定义一次对DefaultModelValidatorProviders的绑定。

     

来源=     堆栈跟踪:   

您能提供一种方法来让NInject在WebApi控制器中注册吗?

0 个答案:

没有答案