2012-06-01 3 views
37

Я только что установил обновление mvc4 rc, и я пытаюсь создать приложение api с небольшой удачей.Связывание веб-API ASP.NET с ninject

Я использую ninject, но не могу загрузить мои контроллеры. Я получаю сообщение об ошибке

Тип «Api.Controllers.ConsumerController» не имеет конструктор по умолчанию

Я новичок в MVC и с помощью инъекции, так, пожалуйста, медведь со мной.

я нету сделал ничего особенного связывания, что по умолчанию создается с помощью NuGet

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) 
    { 
     kernel.Bind<IConsumerRepository>().To<ConsumerRepository>(); 
    }   
} 

Мой контроллер выглядит

private readonly IConsumerRepository _repository; 

    public ConsumerController(IConsumerRepository repository) 
    { 
     _repository = repository; 
    } 

    [HttpGet] 
    public IQueryable<Consumer> Get(Guid id) 
    { 
     return _repository.Get(id).AsQueryable(); 
    } 

Что мне нужно сделать, чтобы получить контроллеры API для работы с Ninject?

Извините, если это простые вещи

Я попробовал ваше предложение Майкла, однако после того, как изменения в webcommon.cs к этому

private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

     RegisterServices(kernel); 
     GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(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) 
    { 
     kernel.Bind<IConsumerRepository>().To<ConsumerRepository>(); 
    } 

Я получаю сообщение об ошибке при

var kernel = new StandardKernel(); 

называется

Метод «GetFilters» в типе «Ninject.Web.WebApi.Filter.DefaultFilterProvider» из сборки «Ninject.Web.WebApi, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = c7192dc5380945e7» не имеет реализации.

Что мне не хватает?

ответ

60

Я спросил Brad Wilson об этом, и он изменился в MVC4 RC.

GlobalConfiguration.Configuration.ServiceResolver был перемещен в GlobalConfiguration.Configuration.DependencyResolver

Используйте эту реализацию, чтобы создать Ninject DependencyResolver для Web Api: https://gist.github.com/2417226

In NinjectWebCommon.cs:

// Register Dependencies 
RegisterServices(kernel); 

// Set Web API Resolver 
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 
+0

Привет, Майкл, когда я использую ваше предложение, я получаю сообщение об ошибке «GetFilters» в типе «Ninject.Web.WebApi.Filter.DefaultFilterProvider» из сборки «Ninject.Web.WebApi, Version = 3.0.0.0, Culture = neutral, PublicKeyToken = c7192dc5380945e7 'не имеет реализации. –

+3

Я удалил ссылку на webapi и, похоже, решил. –

+1

Я думаю, вы используете плагин Ninject, предназначенный для более старой версии WebApi. Удалите эту ссылку и используйте только пакеты Nuget ** Ninject **, ** Ninject.Web.Common ** и ** Ninject.MVC3 ** _ (все еще работает для MVC4) _ –

0

Вы зарегистрировали контейнер с обложкой? Я предпочитаю использовать autofac, вот пример использования autofac с API. http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx

Кроме того, Марк Симэн имеет хороший пост на DI в целом с WebAPI

http://blog.ploeh.dk/2012/03/20/RobustDIWithTheASPNETWebAPI.aspx

От Ploeh:

GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
    t => this.container.Kernel.HasComponent(t) ? 
     this.container.Resolve(t) : 
     null, 
    t => this.container.ResolveAll(t).Cast<object>()); 

Приведенный выше должна быть выполнена в global.asax

6

Это общее сообщение об ошибке

Тип 'Api.Controllers.ConsumerContro ller 'не имеет конструктора по умолчанию

также может возникнуть, если вы не делаете свой конструктор общедоступным или не можете разрешить проблему с помощью контейнера IoC из-за отсутствующего аргумента.

Сообщение об ошибке вводит в заблуждение, если не сказать больше.

+0

Так просто, но частный конструктор был моей проблемой, и я проверял все, но я не мог его увидеть, ваш намек спас меня еще на один день. – VahidNaderi

+0

У меня был конструктор, который запросил интерфейс, который был связан с классом, который запросил другой интерфейс - этот интерфейс не имел привязки и вместо того, чтобы сообщить мне об этом - он просто сказал, что ApiController не имеет конструктора по умолчанию - дважды проверьте, зарегистрированы ли ваши зависимости, если вы это получили. –

0

Надеется, что это помогает кто-то еще ...

у меня был тем же вопрос, и это было связанно со мной двигается класс, ответственный за регистрацию сборки отвечает инициализацию контроллеров. Перемещено из веб-проекта.

Использование Autofac, но оно применимо и к другим контейнерам.

звала:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 

Который работает хорошо, когда оно находится в пределах веб-приложения, но бросил выше исключение, когда переехал в рамках проекта, поскольку выполнение сборки больше не содержит контроллеры.

Вместо пришлось обновить до:

builder.RegisterApiControllers(Assembly.GetCallingAssembly()); 
0

Кажется Ninject не сгенерирует исключение, как это обычно происходит, когда ваши зависимости МОК не совсем правильно настроили. Вместо этого он выглядел так, будто я не зарегистрировал преобразователь зависимостей WebAPI, который я, безусловно, сделал. Вот мое решение этой проблемы, но из-за того, что я нашел, это могло быть МНОГО РАЗЛИЧНЫХ типов проблем установки. Просто перепроверьте все в цепочке зависимостей. Надеюсь, это помогает кому-то!

Контроллер:

public class ContestsController : ApiController 
{ 
    //Ninject wouldn't inject this CTOR argument resulting in the error 
    public ContestsController(IContestEntryService contestEntryService) 
    { 

Зависимость:

public class ContestEntryService : IContestEntryService 
{ 

    public ContestEntryService(IContestsContext contestsContext) 
    { 

Неправильная конфигурация:

private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<IContestsContext>() 
       .To<ContestsContext>() 
       .InRequestScope(); 

     kernel.Bind(x => 
      x.FromAssembliesMatching("MyNameSpace.*") 
      .SelectAllClasses() 
      .BindAllInterfaces() 
     ); 

Правильная конфигурация:

private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind(x => 
      x.FromAssembliesMatching("MyNameSpace.*") 
      .SelectAllClasses() 
      .BindAllInterfaces() 
     ); 

     kernel.ReBind<IContestsContext>() 
       .To<ContestsContext>() 
       .InRequestScope(); 

Как правило, Ninject хорошо разбирается в таких ошибках, поэтому я действительно получил бросок для цикла на этом!

6

Вы можете установить пакет WebApiContrib.IoC.Ninject NuGet и добавьте следующую строку кода NinjectWebCommon.cs

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

Это сработало для меня! Спасибо ... Также убедитесь, что вы установили привязки в файле NinjectWebCommon.cs :) –

0

если кто-то все еще возникают проблемы, пожалуйста, слушать некоторые причина Ninject не работает, как можно было бы ожидать с MVC 4. в вашем веб-API, вам нужно написать этот код

public DefaultController() : base() { } 

Это удаляет т он ошибки говорят о конструкторе не по умолчанию, а затем, когда вам нужно, чтобы получить данные из метода GET написать этот код:

public IEnumerable<YourModelGoesHere> Get() 
{ 
    return context.YourData; 
} 

Имейте в виду, вы должны будете получить доступ к классу дб здесь, а также, например:

DefaultConnection context = new DefaultConnection(); 
0

просто установить Ninject.MvcXXX пакет, где XXX - версия MVC ...

0

Я имел это сообщение об ошибке, тоже, но это как раз оказалось, что один из моих интерфейсов фактически не были реализованы любыми классами (я забыл добавить его в объявление класса).

1

Для кого посадки здесь при поиске «... не имеет конструктор по умолчанию» ищет легкий способ отладки беззвучно провала попытки конфигурации:

  1. Удалить конструктор-впрыскивается объекты, пока конструктор не может быть вызван
  2. Для каждого из ранее введенных, теперь неинициализированными объектов, вызовите с помощью:

ServiceLocator.Current.GetInstance<[OBJ-TYPE]>()

Оскорбительный объект вызовет исключение ActivationException с описательным сообщением. У тебя есть что пойти.

Не забудьте удалить звонок в ServiceLocator после исправления. То есть. это не Рекомендация использовать антивирусную функцию локатора службы вне отладки.

Смежные вопросы