MVC5、 Web API 2和 Njet

我使用 Web API 2创建了一个新的 MVC5项目,然后从 NuGet 添加了 Ninject.MVC3包。

构造函数注入在 MVC5控制器中工作得很好,但是我在尝试将它与 Web API 控制器一起使用时遇到了一个错误。

试图创建类型为“ UserProfileController”的控制器时出错。确保控制器具有无参数的公共构造函数。

MVC5控制器的构造函数:

public class HomeController : Controller
{
private IMailService _mail;
private IRepository _repo;


public HomeController(IMailService mail, IRepository repo)
{
_mail = mail;
_repo = repo;
}
}

Constructor for non-working Web API Controller:

public class UserProfileController : ApiController
{
private IRepository _repo;


public UserProfileController(IRepository repo)
{
_repo = repo;
}
}

下面是完整的 ninjectwebcommon.cs 文件:

[assembly: WebActivator.PreApplicationStartMethod(typeof(DatingSite.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(DatingSite.App_Start.NinjectWebCommon), "Stop")]


namespace DatingSite.App_Start
{
using System;
using System.Web;


using Microsoft.Web.Infrastructure.DynamicModuleHelper;


using Ninject;
using Ninject.Web.Common;
using DatingSite.Services;
using DatingSite.Data;


public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();


/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}


/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}


/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();


RegisterServices(kernel);
return kernel;
}


/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
#if DEBUG
kernel.Bind<IMailService>().To<MockMailService>().InRequestScope();


#else
kernel.Bind<IMailService>().To<MailService>().InRequestScope();
#endif
kernel.Bind<SiteContext>().To<SiteContext>().InRequestScope();
kernel.Bind<IRepository>().To<Repository>().InRequestScope();
}
}
}
53012 次浏览

你有这个问题,因为控制器和 APIController 使用不同的依赖解析器。解决方案非常简单。

首先创建依赖解析器和依赖范围的新类:

 public class NinjectResolver : NinjectScope, IDependencyResolver
{
private readonly IKernel _kernel;
public NinjectResolver(IKernel kernel)
: base(kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectScope(_kernel.BeginBlock());
}
}


public 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;
}
}

然后,将下一行添加到 NinjectWebCommon 中的 CreateKernel ()方法

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

Web.WebApi NuGet包裹刚刚发布,从现在开始首选的解决方案是使用这个包。 我找不到任何相关的文档,但在安装了软件包之后,一切都很顺利。

Install-Package Ninject.Web.WebApi

安装完成后,通常的 MVC 和 API 控制器实例都由 Njet 提供。

如果你有注射器。韦伯。通用已经安装确保从 ninjectwebcommon.cs 中保存绑定,并让 Nuget 在安装过程中重写 ninjectwebcommon.cs ,完成后放回绑定。

正如在评论中指出的,根据您的执行上下文,您将需要以下软件包的 :

  • 注入。网络。网络应用程序。网络主机
  • 注入。网络。 WebApi。 OwinHost
  • 注入。网络。网络应用程序。自主

最常见的场景是选择 WebHost 包的 IIS。

如果你从头开始创建一个 IIS MVC5 web 应用程序,并想使用 Njet 安装以下软件包:

  • 注入核心 dll
  • 通用的 Web 功能,例如: Ninje.Web.Common -Ninje.InRequestScope ()的通用 Web 功能
  • Ninject.MVC5 -MVC 依赖性注入器,例如为 MVC 提供控制器
  • 注射。韦伯。常见。WebHost -当 IIS 启动 web 应用程序时,从 Ninject.MVC5注册依赖注入器。如果您没有使用 IIS,那么您将需要一个不同的软件包,请检查以上内容
  • 依赖注入器,例如为 WebApi 提供控制器
  • 当 IIS 启动 Web 应用程序时,注册来自 Ninject 的依赖注入器。

只是对于其他人,谁可能有一个类似的设置,我来到这里通过谷歌像我一样。

我有多个应用程序使用一个 WebApi 项目。如果我没有在 RegisterServices 方法中包含绑定,就会得到上面的错误。所以在拔头发之前,先检查一下你是否绑好了。该错误不会告诉您丢失了绑定。如果应用程序与 WebApi 位于同一个项目中,那么就会出现这种情况。

我也有同样的问题。 安装以下 NuGet 软件包后:

  • 注射
  • Ninject.web WebApi
  • Ninject.web. WebApi. WebHost
  • 注射器 MVC3
  • Ninject.web 常见
  • Ninject.web. Common. WebHost

一切正常

我找到了那个组装 Ninjot。韦伯。Dll 定义自己的 DependencyResolver,并将其注册到 Njet 类的内核中。韦伯。WebApi.自动 WebApiModule。

所以我只需要向 NinjectWebCommon. CreateKernel 添加一行..。

GlobalConfiguration.Configuration.DependencyResolver =
kernel.Get<System.Web.Http.Dependencies.IDependencyResolver>();

最后,我的项目有以下依赖关系:

  • 注入3.2.0
  • 通用3.2.0
  • 注入.Web.WebApi 3.2.4

我最近必须让 WebApi 2工作起来,这样我才能回答这部分问题。

这些是 Web Api 2-所需的 nuget 包

Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
WebActivatorEx

然后编辑 NinjectWebCommon.CreateKernel(..),包括

RegisterServices(kernel);
// the next line is the important one
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;

我已经写了一篇关于这个更详细的文章-http://NoDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/包括一个完整的解决方案下载。

我在一个解决方案中遇到了这个问题,在这个解决方案中,我使用 Njet 的项目没有使用 Web API (到目前为止,我的解决方案中有6个项目)。我不断得到可怕的“所需的无参数构造函数”,这显然意味着当我添加它时,Njet 注入没有得到实例化,因为它被放入了空的构造函数中。我尝试了各种解决方案,但是最后我检查了我的 Njet 软件包,发现。韦伯。安装了 Webapi 包。我卸载了这个,做了一个清洁和重建。这解决了问题。我的另一个较低级别的项目是引用 Nregister。韦伯。Api 包和愚蠢的我已经安装到我的 Web 前端项目。

我希望这可以帮助其他尝试了所有 Stack 解决方案但没有任何进展的人。

你应该在 webAPI 项目中从 Nuget 安装这些软件包。

  1. 注射
  2. 注射器,网络,通用
  3. 注入。网络。公共。网络主机
  4. 注射器,网络,网络应用
  5. 注入。网络。网络应用程序。网络主机

然后,还必须在 Repository 项目中安装 Ninject包(版本必须与 API 项目中的版本相同)。我在安装了不同版本的 Njet 时也遇到了同样的问题。