MVC5, Web API 2 및 Ninject
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;
}
}
작동하지 않는 Web API 컨트롤러의 생성자 :
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();
}
}
}
Ninject.Web.WebApi NuGet 패키지 가 방금 출시되었습니다. 이제부터 선호하는 솔루션은 해당 패키지를 사용하는 것입니다. 관련 문서를 찾을 수 없었지만 패키지를 설치 한 후 모든 것이 저에게 효과적이었습니다.
Install-Package Ninject.Web.WebApi
설치 후 Ninject에서 일반 MVC 및 API 컨트롤러 인스턴스를 모두 제공합니다.
Ninject.Web.Common이 이미 설치되어있는 경우 NinjectWebCommon.cs에서 바인딩을 저장하고 Nuget이 설치 중에 NinjectWebCommon.cs를 다시 작성하도록하고 완료되면 바인딩을 다시 넣으십시오.
실행 컨텍스트에 따라 주석에서 지적했듯이 다음 패키지 중 하나도 필요 합니다.
- Ninject.Web.WebApi.WebHost
- Ninject.Web.WebApi.OwinHost
- Ninject.Web.WebApi.Selfhost
가장 일반적인 시나리오는 WebHost 패키지를 선택하는 IIS입니다.
IIS MVC5 웹 앱을 처음부터 시작하고 Ninject를 사용하려는 경우 다음 패키지를 설치하십시오.
- Ninject -Ninject 코어 DLL
- Ninject.Web.Common -Ninject의 일반적인 웹 기능 예. InRequestScope ()
- Ninject.MVC5 - MVC dependency injectors eg. to provide Controllers for MVC
- Ninject.Web.Common.WebHost - Registers the dependency injectors from Ninject.MVC5 when IIS starts the web app. If you are not using IIS you will need a different package, check above
- Ninject.Web.WebApi WebApi dependency injectors eg. to provide Controllers for WebApi
- Ninject.web.WebApi.WebHost - Registers the dependency injectors from Ninject.Web.WebApi when IIS starts the web app.
You have this problem because Controller and ApiController use different Dependency Resolvers. Solution is very simple.
At first create new classes of Dependency Resolver and Dependency Scope. You can use this:
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;
}
}
After that, add next line to method CreateKernel() in NinjectWebCommon
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
I had the same problem. After installation of the following NuGet packages:
- Ninject
- Ninject.web.WebApi
- Ninject.web.WebApi.WebHost
- Ninject.MVC3
- Ninject.web.Common
- Ninject.web.Common.WebHost
everything works fine
I'm found that assembly Ninject.Web.WebApi.dll define own DependencyResolver and register it with kernel in class Ninject.Web.WebApi.WebApiModule automatically.
So I simply add to NinjectWebCommon.CreateKernel one line...
GlobalConfiguration.Configuration.DependencyResolver =
kernel.Get<System.Web.Http.Dependencies.IDependencyResolver>();
Finally my project has following dependencies:
- Ninject 3.2.0
- Ninject.Web.Common 3.2.0
- Ninject.Web.WebApi 3.2.4
Just for others, who might have a similar set up to me, and got here via google like I did.
I had multiple applications using one WebApi project. I would get the above error if I hadn't included the binding in the RegisterServices method. So before pulling your hair out, just check you have the binding set up. The error doesn't tell you you have missing bindings. Which it would if the Application is in the same project as the WebApi.
I recently had to get Web Api 2 working with so I can answer that part of the question.
These are the nuget packages needed for Web Api 2-
Ninject
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.WebApi
WebActivatorEx
Then edit NinjectWebCommon.CreateKernel(..)
including
RegisterServices(kernel);
// the next line is the important one
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
I've written a more detailed post about this - http://NoDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/ including a full solution to download.
I had this issue in a solution where the project in which I was using Ninject was not using Web API (I have 6 projects so far in my solution). I kept on getting the dreaded "parameterless constructor required" which obviously meant when I added it the Ninject injection was not getting instantiated as it was dropping into the empty constructor. I tried various solutions but in the end I checked my Ninject packages and saw that the Ninject.Web.Webapi package was installed. I uninstalled this and did a clean and rebuild. This solved the issue. My other lower level project was referencing the Ninject.Web.Api package and stupidly I had installed that into my Web front end project.
I hope this may help other people who have tried all the Stack solutions and got no where.
참고URL : https://stackoverflow.com/questions/20595472/mvc5-web-api-2-and-ninject
'Nice programing' 카테고리의 다른 글
UILabel 높이를 동적으로 계산하는 방법은 무엇입니까? (0) | 2020.10.25 |
---|---|
순수 CSS 닫기 버튼 (0) | 2020.10.25 |
base64 문자열을 ArrayBuffer로 변환 (0) | 2020.10.25 |
SourceTree에서 커밋되지 않은 변경 사항을 버리는 방법은 무엇입니까? (0) | 2020.10.25 |
SQL Server에서 주어진 테이블에 대해 CREATE TABLE 문을 어떻게 생성합니까? (0) | 2020.10.25 |