【问题标题】:Ninject doesn't resolve dependency (parameterless constructor error)Ninject 不解决依赖关系(无参数构造函数错误)
【发布时间】:2015-08-13 08:42:09
【问题描述】:

我正在努力在 Web 服务应用程序中启用 Ninject 的构造函数注入。这是我采取的步骤(Visual Studio 2013):

1) 使用“ASP.NET Web 应用程序”模板创建了一个新项目。

2) 在项目创建向导的第二步中选择了一个“Empty”应用程序模板。

3) 在名为“添加文件夹和核心引用”的第三步中选择“Web API”

4) 项目已创建,现在我添加了一个类型为“Web API 2 Controller - Empty”的控制器。添加如下代码:

using System.Web.Http;

namespace WebApplication1.Controllers
{
    public interface IDummy
    {
    }

    public class Dummy : IDummy
    {
    }

    public class DefaultController : ApiController
    {
        public DefaultController(IDummy dummy)
        {
        }

        [HttpGet]
        [Route("")]
        public string Index()
        {
            return "Hello World!";
        }
    }
}

5) 已安装 NuGet 包:Ninject.Web.WebApi(WebApi2 的 Ninject 集成),现在我在其他线程中发现要使其与 IIS 一起工作,我需要安装 Ninject.Web.Common.WebHost 包。之后,AppStart 中出现了 NinjectWebCommon.cs 文件。我对该文件所做的唯一编辑是在 RegisterServices 方法中:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IDummy>().To<Dummy>();
}

现在,当我尝试运行应用程序(在本地,只需在 Visual Studio 中按 F5)时,我希望在浏览器中获取 Hello World 字符串,但我却得到了臭名昭著的无参数构造函数错误: 这意味着我猜 Ninject 出于某种原因没有完成它的工作。不幸的是,到目前为止,谷歌搜索解决方案没有结果。任何人都可以提示我该怎么做才能完成这项工作?提前致谢。

【问题讨论】:

  • 您是否安装了WebActivatorEx?
  • 是的,Ninject.Web.Common.WebHost 包依赖它。
  • 您是否安装了nuget.org/packages/Ninject.MVC3?认为您需要它,以便 Ninject 知道连接控制器
  • 我尝试添加它。现在应用程序在 NinjectWebCommon.CreateKernel() 中抛出 FileNotFoundException “无法加载文件或程序集 'System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 或其依赖项之一。系统找不到指定的文件。”请注意,我在创建项目时没有选择MVC模板(它不是网页,不会有任何视图)。

标签: c# dependency-injection ninject asp.net-web-api2


【解决方案1】:

通过使用this solution,我能够非常简单地完成这项工作。只需安装Ninject.Web.WebApi,然后添加如下代码即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Ninject;
using Ninject.Activation;
using Ninject.Parameters;
using Ninject.Syntax;

internal class NinjectDependencyResolver : NinjectScope, IDependencyResolver
{
    private readonly IKernel kernel;

    public NinjectDependencyResolver(IKernel kernel)
        : base(kernel)
    {
        if (kernel == null)
            throw new ArgumentNullException("kernel");

        this.kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NinjectScope(this.kernel.BeginBlock());
    }
}

internal class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;
    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }
    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }
    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }
    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

用法

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        IKernel kernel = new StandardKernel();

        kernel.Bind<IDummy>().To<Dummy>();

        config.DependencyResolver = new NinjectDependencyResolver(kernel);

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

【讨论】:

  • 工作,也正如你所指出的,但我会强调这一点,现在我不需要 Ninject.Web.Common.WebHost 包:)。谢谢。
  • 感谢您为设置场景提供分步说明。它使回答您的问题变得轻而易举。
猜你喜欢
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
相关资源
最近更新 更多