web-dev-qa-db-fra.com

Liaison API Web ASP.NET avec ninject

Je viens d'installer la mise à jour mvc4 rc et j'essaie de créer une application api avec un peu de chance.

J'utilise ninject mais je ne peux pas charger mes contrôleurs. je continue d'avoir une erreur

Le type 'Api.Controllers.ConsumerController' n'a pas de constructeur par défaut

Je suis très nouveau à MVC et en utilisant l'injection alors s'il vous plaît supporter avec moi.

Je n'ai rien fait de spécial avec la liaison par défaut créée via 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>();
    }        
}

Mon contrôleur ressemble à

   private readonly IConsumerRepository _repository;

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

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

Que dois-je faire pour que les contrôleurs API fonctionnent avec ninject?

Désolé si c'est simple

J'ai essayé votre suggestion Michael cependant après avoir changé le webcommon.cs à cette

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

Je reçois une erreur quand 

var kernel = new StandardKernel();

est appelé

La méthode 'GetFilters' du type 'Ninject.Web.WebApi.Filter.DefaultFilterProvider' dans Assembly 'Ninject.Web.WebApi, Version = 3.0.0.0, Culture = neutre, PublicKeyToken = c7192dc5380945e7' n'a pas d'implémentation.

Qu'est-ce que je rate?

36
Diver Dan

J'ai demandé Brad Wilson à ce sujet et cela a changé dans MVC4 RC.

GlobalConfiguration.Configuration.ServiceResolver a été déplacé vers GlobalConfiguration.Configuration.DependencyResolver

Utilisez cette implémentation pour créer un Ninject DependencyResolver pour votre API Web: https://Gist.github.com/2417226

Dans NinjectWebCommon.cs:

// Register Dependencies
RegisterServices(kernel);

// Set Web API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
60
Michael Baird

Vous pouvez installer le package NuGet WebApiContrib.IoC.Ninject et ajouter la ligne de code suivante à NinjectWebCommon.cs.

GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
6
Ryan Spears

Ce message d'erreur générique

Le type 'Api.Controllers.ConsumerController' n'a pas de constructeur par défaut

cela peut également se produire si vous ne rendez pas votre constructeur public ou si la dépendance ne peut pas être résolue par le conteneur IoC, peut-être à cause d'un argument manquant.

Le message d'erreur est pour le moins trompeur.

6
badikumar

Je sais que c’est un vieux post, mais j’ai trouvé la solution à un certain lien, alors je le partage ici. J'espère que ça aide.

http://weblogs.asp.net/hajan/archive/2013/03/16/quick-tip-how-to-make-nake-work-with-asp-net-web-api.aspx?CommentPosted= true # commentmessage

0
Rasshme Chawla

si quelqu'un vous pose encore des problèmes, veuillez écouter pour une raison quelconque. Ninject ne fonctionne pas comme prévu. Avec mvc 4. Dans votre API Web, vous devez écrire ce code 

public DefaultController() : base() { }  

Cela supprime l'erreur indiquant qu'il n'y a pas de constructeur par défaut. Lorsque vous devez récupérer vos données à partir de la méthode get, écrivez ce code: 

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

N'oubliez pas que vous devrez également accéder à votre classe de base de données ici, par exemple: 

DefaultConnection context = new DefaultConnection(); 
0
user3247368

Espérons que cela aide quelqu'un d'autre ...

J'avais le même problème et il était lié à mon déplacement de classe responsable de l'enregistrement de l'Assemblée chargé d'initialiser les contrôleurs. Déplacé du Web dans le projet cadre.

Utiliser Autofac mais la même chose s’appliquerait pour d’autres conteneurs.

Appelait:

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

Ce qui fonctionne bien lorsqu'il se trouve dans une application Web, mais avec une exception ci-dessus lorsqu'il est déplacé vers un projet-cadre, car l'assemblage en cours d'exécution ne contient plus les contrôleurs.

Au lieu de cela a dû mettre à jour à:

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

Il semble que Ninject n'a pas lancé d'exception comme c'est généralement le cas lorsque vos dépendances IOC ne sont pas correctement configurées. Cela donnait plutôt l'impression que je n'avais pas enregistré le résolveur de dépendances WebAPI, ce que j'ai certainement fait. Voici ma solution à ce problème, mais d'après ce que j'ai découvert, il pourrait s'agir de nombreux types de problèmes d'installation. Il suffit de vérifier à nouveau tout dans la chaîne de dépendance. J'espère que ça aide quelqu'un!

Le controlle:

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

La dépendance:

public class ContestEntryService : IContestEntryService
{

    public ContestEntryService(IContestsContext contestsContext)
    {

La configuration incorrecte:

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

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

La configuration correcte:

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

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

En général, Ninject est plutôt doué pour signaler ce genre d’erreurs, alors j’ai vraiment eu la chance de faire une boucle sur celle-ci!

0
John Culviner

installez simplement le package Ninject.MvcXXX, où XXX - version de MVC ...

0
Andrey Burykin

J'ai également eu ce message d'erreur, mais il s'est avéré qu'une de mes interfaces n'était implémentée par aucune classe (j'ai oublié de l'ajouter à la déclaration de classe).

0
Mark Cidade

avez-vous enregistré le conteneur avec le frawework? Je préfère utiliser autofac. Voici un exemple d'utilisation d'Autofac avec API. http://alexmg.com/post/2012/03/08/Autofac-ASPNET-Web-API-%28Beta%29-Integration.aspx

En outre, Mark Seeman a un bon post sur DI en général avec WebAPI

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

De Ploeh: 

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

Ce qui précède doit être effectué dans le fichier global.asax. 

0
jflood.net