Ich habe ein neues MVC5-Projekt mit Web-API 2 erstellt und dann das Ninject.MVC3-Paket von NuGet hinzugefügt.
Die Konstruktorinjektion funktioniert gut für die MVC5-Controller, aber ich erhalte eine Fehlermeldung, wenn ich versuche, sie mit den Web-API-Controllern zu verwenden.
Beim Versuch, einen Controller vom Typ 'UserProfileController' zu erstellen, ist ein Fehler aufgetreten. Stellen Sie sicher, dass der Controller über einen parameterlosen öffentlichen Konstruktor verfügt.
Konstruktor für den funktionierenden MVC5-Controller:
public class HomeController : Controller
{
private IMailService _mail;
private IRepository _repo;
public HomeController(IMailService mail, IRepository repo)
{
_mail = mail;
_repo = repo;
}
}
Konstruktor für nicht funktionierenden Web-API-Controller:
public class UserProfileController : ApiController
{
private IRepository _repo;
public UserProfileController(IRepository repo)
{
_repo = repo;
}
}
Unten finden Sie die vollständige Datei 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();
}
}
}
Antworten:
Das Ninject.Web.WebApi NuGet- Paket wurde gerade veröffentlicht. Von nun an verwendet die bevorzugte Lösung dieses Paket. Ich konnte keine zugehörige Dokumentation finden, aber nach der Installation des Pakets funktionierte alles für mich.
Nach der Installation werden sowohl die normalen MVC- als auch die API-Controller-Instanzen von Ninject bereitgestellt.
Wenn Sie Ninject.Web.Common bereits installiert haben, speichern Sie Ihre Bindungen aus NinjectWebCommon.cs und lassen Sie Nuget NinjectWebCommon.cs während der Installation neu schreiben und Ihre Bindungen zurücksetzen, wenn Sie fertig sind.
Wie in den Kommentaren erwähnt, benötigen Sie abhängig von Ihrem Ausführungskontext auch eines der folgenden Pakete:
Das häufigste Szenario ist IIS für die Auswahl des WebHost-Pakets.
Wenn Sie eine IIS MVC5-Webanwendung von Grund auf neu starten und Ninject verwenden möchten, installieren Sie die folgenden Pakete:
quelle
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
nachRegisterServices(kernel);
Sie haben dieses Problem, weil Controller und ApiController unterschiedliche Abhängigkeitsauflöser verwenden. Die Lösung ist sehr einfach.
Erstellen Sie zunächst neue Klassen von Dependency Resolver und Dependency Scope. Sie können dies verwenden:
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; } }
Fügen Sie danach die nächste Zeile zur Methode CreateKernel () in NinjectWebCommon hinzu
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
quelle
Ich hatte das gleiche Problem. Nach der Installation der folgenden NuGet-Pakete:
alles funktioniert gut
quelle
Ninject.web.WebApi.WebHost
für die Unterstützung bedanken!Ich habe festgestellt, dass die Assembly Ninject.Web.WebApi.dll einen eigenen DependencyResolver definiert und ihn automatisch beim Kernel in der Klasse Ninject.Web.WebApi.WebApiModule registriert.
Also füge ich einfach eine Zeile zu NinjectWebCommon.CreateKernel hinzu ...
Schließlich hat mein Projekt folgende Abhängigkeiten:
quelle
Nur für andere, die vielleicht ein ähnliches Setup wie ich haben und wie ich über Google hierher gekommen sind.
Ich hatte mehrere Anwendungen mit einem WebApi-Projekt. Ich würde den obigen Fehler erhalten, wenn ich die Bindung nicht in die RegisterServices-Methode aufgenommen hätte. Überprüfen Sie also vor dem Herausziehen der Haare, ob die Bindung eingerichtet ist. Der Fehler sagt Ihnen nicht, dass Sie fehlende Bindungen haben. Was wäre, wenn sich die Anwendung im selben Projekt wie das WebApi befindet.
quelle
Ich musste kürzlich Web Api 2 zum Laufen bringen, damit ich diesen Teil der Frage beantworten kann.
Dies sind die Nuget-Pakete, die für Web Api 2- benötigt werden.
Dann bearbeiten Sie
NinjectWebCommon.CreateKernel(..)
einschließlichIch habe einen ausführlicheren Beitrag dazu geschrieben - http://NoDogmaBlog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/ einschließlich eines vollständigen Lösung zum Download.
quelle
Sie sollten diese Pakete von Nuget in einem webAPI-Projekt installieren.
Anschließend müssen Sie das
Ninject
Paket auch im Repository-Projekt installieren (die Version muss mit der im API-Projekt identisch sein). Ich hatte das gleiche Problem, als für Ninject eine andere Version installiert war.quelle
Ich hatte dieses Problem in einer Lösung, in der das Projekt, in dem ich Ninject verwendete, keine Web-API verwendete (ich habe bisher 6 Projekte in meiner Lösung). Ich bekam immer wieder den gefürchteten "parameterlosen Konstruktor erforderlich", was offensichtlich bedeutete, dass die Ninject-Injektion beim Hinzufügen nicht instanziiert wurde, da sie in den leeren Konstruktor fiel. Ich habe verschiedene Lösungen ausprobiert, aber am Ende habe ich meine Ninject-Pakete überprüft und festgestellt, dass das Ninject.Web.Webapi-Paket installiert wurde. Ich habe dies deinstalliert und sauber gemacht und neu aufgebaut. Dies löste das Problem. Mein anderes Projekt auf niedrigerer Ebene bezog sich auf das Ninject.Web.Api-Paket, und dummerweise hatte ich das in mein Web-Front-End-Projekt installiert.
Ich hoffe, dies kann anderen Leuten helfen, die alle Stack-Lösungen ausprobiert haben und keine Ahnung haben.
quelle