MVC5, Web API 2 и Ninject
Я создал новый проект MVC5 с Web API 2, Затем я добавил Ninject.Пакет MVC3 от NuGet.
инъекция конструктора работает нормально для контроллеров 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();
}
}
}
7 ответов:
Ninject.Сеть.WebApi NuGet пакета только что был освобожден. Отныне предпочтительным решением является использование этого пакета. Я не мог найти никакой связанной документации, но после установки пакета все работало для меня.
Install-Package Ninject.Web.WebApiпосле установки как обычные экземпляры MVC, так и экземпляры контроллера API предоставляются Ninject.
Если у вас есть Ninject.Сеть.Общие уже установлены убедитесь, что сохранить привязки от NinjectWebCommon.cs и пусть Nuget перепишет NinjectWebCommon.cs во время установки и вернуть привязки, когда закончите.
Как указано в комментариях в зависимости от контекста выполнения вам понадобится один из следующих пакетов:
- Ninject.Сеть.Веб-API.Хостинг
- Ninject.Сеть.Веб-API.OwinHost
- Ninject.Сеть.Веб-API.Selfhost
наиболее распространенным сценарием является IIS для этого выбора веб-узла пакет.
Если вы запускаете веб-приложение IIS MVC5 с нуля и хотите использовать Ninject, установите следующие пакеты:
- Ninject - Ninject core dll
- Ninject.Сеть.Общий - общие веб-функции для Ninject например. InRequestScope()
- Ninject.MVC5 - инжекторы зависимости MVC, например. обеспечить регуляторы для MVC
- Ninject.Сеть.Общий.Хостинг - регистрирует инжекторы зависимостей от Ninject.MVC5, когда IIS запускает веб-приложение. Если вы не используете IIS вам понадобится другой пакет, проверьте выше
- Ninject.Сеть.Веб-API инжекторы зависимостей WebApi, например. чтобы обеспечить контроллеры для WebApi
- Ninject.сеть.Веб-API.Хостинг - регистрирует инжекторы зависимостей от Ninject.Сеть.WebApi при запуске IIS в интернете приложение.
у вас есть эта проблема, потому что контроллер и 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; } }после этого добавьте следующую строку в метод CreateKernel () в NinjectWebCommon
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
У меня была та же проблема. После установки следующих пакетов NuGet:
- Ninject
- Ninject.сеть.Веб-API
- Ninject.сеть.Веб-API.Хостинг
- Ninject.MVC3
- Ninject.сеть.Общий
- Ninject.сеть.Общий.Хостинг
все работает нормально
Я нашел, что сборка Ninject.Сеть.Веб-API.dll определяет собственный DependencyResolver и регистрирует его с ядром в классе Ninject.Сеть.Веб-API.WebApiModule автоматически.
поэтому я просто добавляю в NinjectWebCommon.CreateKernel одна строка...
GlobalConfiguration.Configuration.DependencyResolver = kernel.Get<System.Web.Http.Dependencies.IDependencyResolver>();наконец-то мой проект имеет следующие зависимости:
- Ninject 3.2.0
- Ninject.Сеть.Общие 3.2.0
- Ninject.Сеть.Веб-API 3.2.4
только для других, которые могут иметь аналогичную настройку для меня, и попали сюда через google, как и я.
У меня было несколько приложений, использующих один проект WebApi. Я бы получил вышеуказанную ошибку, если бы я не включил привязку в метод RegisterServices. Поэтому, прежде чем вытаскивать волосы, просто проверьте, что у вас есть привязка. Ошибка не говорит вам, что у вас есть недостающие привязки. Что было бы, если приложение находится в том же проекте, что и WebApi.
недавно мне пришлось работать с Web Api 2, чтобы я мог ответить на эту часть вопроса.
Это пакеты nuget, необходимые для Web Api 2 -
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/ включая полное решение для загрузки.
У меня была эта проблема в решении, где проект, в котором я использовал Ninject, не использовал веб-API (у меня есть 6 проектов до сих пор в моем решении). Я продолжал получать страшный "конструктор без параметров", который, очевидно, означал, что когда я добавил его, инъекция Ninject не создавалась, поскольку она падала в пустой конструктор. Я пробовал различные решения, но в конце концов я проверил свои пакеты Ninject и увидел, что Ninject.Сеть.Был установлен пакет Webapi. Я удалил это и сделал чистую и перестроить. Это решило проблему. Мой другой проект более низкого уровня ссылался на Ninject.Сеть.Пакет Api и глупо я установил это в свой веб-проект переднего плана.
Я надеюсь, что это может помочь другим людям, которые пробовали все решения стека и не получили где.
Comments