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();
}
}
}
679   7  

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

    Ничего не найдено.