首页 > 解决方案 > NInject v3.3.4 和 WebApi 2,没有无参数构造函数

问题描述

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

其中之一在 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。

来源=堆栈跟踪:

为此,我尝试了我在 SO 某处读到的 hack。我在调用 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 Message=错误激活 DefaultModelValidatorProviders 有多个匹配的绑定可用。匹配绑定:1)从 DefaultModelValidatorProviders 绑定到常量值 2)从 DefaultModelValidatorProviders 绑定到常量值激活路径:2)将依赖项 DefaultModelValidatorProviders 注入到 NinjectDefaultModelValidatorProvider 类型的构造函数的参数 defaultModelValidatorProviders 1)对 ModelValidatorProvider 的请求

建议: 1) 确保您只为 DefaultModelValidatorProviders 定义了一次绑定。

来源=堆栈跟踪:

你能提供一种方法让 NInject 注册到 WebApi 控制器吗?

标签: c#asp.net-web-apininject

解决方案


推荐阅读