9
votes

Singleton Scope Binding ne fonctionne pas comme prévu

J'utilise le plugin NINJECT MVC3 avec ma demande d'API Web. J'ai une contraignante qui ressemble à:

kernel.bind (). Pour (). INSINGLETONSCOPE ();

C'est mon interprétation que Le Kernal créera exactement une instance de foo et la réutilisera de manière appropriée. En mettant un point d'arrêt dans le constructeur foo , je peux clairement voir qu'il est appelé une fois par demande, et je ne peux pas expliquer pourquoi.

Mes seules devinez est que Le nouveau noyau est créé par demande, mais cela ne semble pas être le cas, en tant que méthode Createkernel qui définit le résolveur de dépendance globale ne fait que s'exécuter une fois dans la durée de vie de l'application.

J'utilise du code pris de Ce message pour faire un jeu de noinject agréable avec MVC 4. En raison de changements de cadre, je devais créer une enveloppe supplémentaire que j'ignifie à globalconfiguration.configuration.dependencyresolver : < Pré> xxx

Qu'est-ce que je fais mal?


1 commentaires

Peut-être pas liée à la question de Captncraig, mais pertinente pour le titre. J'ai eu le même problème et il s'est avéré que j'ai accidentellement injecté la mise en œuvre dans l'un de mes objets plutôt que l'interface. Donc, dans le constructeur, j'avais accidentellement mis FOO au lieu d'ifoo. J'espère que cela aide quelqu'un là-bas ...


4 Réponses :


1
votes

Remarque: j'ai utilisé Nuget pour installer Ninject & ninject.web.mvc (que je suis sûr que vous avez fait aussi bien).

Je ne suis pas capable de voir le reste de votre code, mais voici ce que j'avais Dans ma classe "NinjectDePendePenScope". (Je pense que le vôtre est juste appelé NinjectScope, pourrait être des autres incohérences de nommer avec votre code) p> xxx pré>

et voici ma classe NInjectWebCommon (situé dans l'App_Start Dossier): P >

using System;
using System.Web;
using System.Web.Http;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Modules;
using Ninject.Web.Common;

[assembly: WebActivator.PreApplicationStartMethod(typeof(ABCD.Project.Web.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(ABCD.Project.Web.App_Start.NinjectWebCommon), "Stop")]

namespace ABCD.Project.Web.App_Start
{
public static class NinjectWebCommon 
{
    private static readonly Bootstrapper Bootstrap = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        Bootstrap.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        Bootstrap.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);

        // Set Web API Resolver
        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)
    {
        //var modules = new INinjectModule[] { new NinjectBindingModule(), };
        //kernel.Load(modules);
        Here's where you would load your modules or define your bindings manually...
    }        
}
}


6 commentaires

Mon contrôleur nécessite un ibar qui prend un ifoo dans le constructeur.


Ours avec moi pendant que je me remette à la vitesse de mon ancienne application API Web MVC 4 qui a utilisé Ninject ... Votre échantillon de code semble un peu familier à ce que j'avais fait ...


Je pense que quelque chose d'étrange se passe-t-il. Votre code semble très similaire à celui de la mienne, sauf que vous utilisez _resolver.tryget et j'ai utilisé _resolver.resolve . Les méthodes tryget n'existent pas sur ma version de irrésolutionroot . Utilisez-vous le plugin MVC3?


J'utilise l'extension Ninject.mvc. D'après ce que je peux voir à ma fin, Tryget est une méthode d'extension pour IRESOLUTIONROOT dans NINJECT DLL. Quelles versions de ces packages Nuge utilisez-vous? J'ai Ninject 3.0.1.10, Ninject.web.common 3.0.0.7 et Ninject.mvc3 3.0.0.6


On dirait que je devais ajouter "à l'aide de Ninject.Syntax" pour obtenir la méthode de l'extension Tryget pour fonctionner également.


J'ai le même NinjectDependencope en tant que captncraig et que je reçois toujours le même problème, avez-vous déjà reçu cela résolu correctement?



5
votes

Je n'ai jamais pu le faire fonctionner correctement et je ne sais pas pourquoi. Je suppose que cela a quelque chose à voir avec l'intégration MVC4 étant un peu immature pour le moment.

comme une alternative que j'utilise:

kernel.bind (). TOCONSANT (Nouveau FOO ());

Cela semble fonctionner, mais je ne suis pas trop content de cela.



4
votes

Comme mentionné précédemment, cela ressemble à un bug.
Une option consiste simplement à implémenter une méthode d'extension singleton vous-même: xxx

puis utilisez simplement: xxx

plutôt < Pré> xxx


0 commentaires

4
votes

En arrivant certainement en retard à ce fil, mais cela m'est arrivé avec un service Windows Hébergement d'Owin pour les contrôleurs d'API Web et de résoudre les dépendances avec Ninject, Inspingletonscope () ne fonctionnait pas tant que je ne faisais pas ce qui suit:

var kernel = new StandardKernel();
...
kernel.Bind<Foo>().ToSelf().InSingletonScope();
kernel.Bind<IFoo>().ToMethod(context => context.Kernel.Get<Foo>());
...

// Controllers ask for the dependency as usual...
public class SomeController : ApiController
{
    readonly IFoo _foo;

    public SomeController(IFoo foo)
    {
        _foo = foo;
    }
...


1 commentaires

Merci de résoudre mon problème, aussi avec des contrôleurs WebAPI, si quelqu'un a une explication claire pourquoi .. Je m'intéresse!