Façons de configurer un singleton Ninject

J’ai une classe ( MyFacade ) à laquelle j’ai injecté un ou plusieurs parameters avec Ninject :

 class MyFacade { IDemoInterface demo; public MyFacade(IDemoInterface demo) { this.demo = demo; } public void MyMethod() { Console.WriteLine(demo.GetInfo()); } } 

Bien sûr, je dois configurer le Ninject pour injecter l’implémentation appropriée de mon paramètre ( IDemoInterface )

Je sais que je peux instancier MyFacade object MyFacade en faisant kernel.Get(); sans rien mettre d’autre. Actuellement ma façade n’a pas d’interface (car c’est ma seule implémentation, je vais peut-être append son interface pour les propositions standard)

si je veux rendre cette façade singlenton unique, je connais deux méthodes: créer un constructeur vide et transmettre un paramètre en procédant de la manière suivante: kernel.Get(); ou par le programme d’installation Ninject comme: kernel.Bind().To().InSingletonScope();

Le second semble être une meilleure approche, mais connaissez-vous un autre moyen de l’installer de manière unique?

Lors de la configuration de vos liaisons, vous devez lier vos dépendances. Il est toujours préférable de configurer vos dépendances dans vos liaisons, au lieu de faire un kernel.Get() dans un constructeur. Vous utilisez IOC, utilisez donc le cadre que vous utilisez pour effectuer l’injection pour vous.

Dans votre deuxième exemple de liaison, ce qui vous manque, c’est une liaison dans votre IDemoInterface . Vos reliures devraient ressembler à ceci:

 //bind the dependency to the implementation. kernel.Bind().To(); //since you bound your dependency, ninject should now have // all the dependencies required to instantiate your `MyFacade` object. kernel.Bind.To().InSingletonScope(); 

Si vous ne souhaitez pas que le conteneur gère le cycle de vie de votre singleton à l’aide de InSingletonScope() , mais souhaitez tout de même l’injecter, je peux penser à deux façons de le faire. Choisissez celui qui convient le mieux à vos besoins. Considérez l’ ISingleton (nommez votre interface) suivante:

 public class ConcreteSingleton : ISingleton { private static readonly Lazy _instance = new Lazy(() => new ConcreteSingleton()); private ConcreteSingleton() { } public static ConcreteSingleton Instance { get { return _instance.Value; } } } 
  1. Modifier la classe singleton pour avoir une GetInstance(...)

    Dans cette méthode (mon approche préférée), vous kernel.Inject(instance) pas kernel.Inject(instance) chaque fois, mais seulement pour la première fois, le singleton est initialisé. Ajout de la méthode suivante à votre classe ConcreteSingleton :

     public static ConcreteSingleton GetInstance(IKernel kernelForInjection) { if (_instance.IsValueCreated == false) { kernelForInjection.Inject(_instance.Value); } return _instance.Value; } 

    Et en utilisant cette reliure:

     kernel.Bind().ToMethod(c => ConcreteSingleton.GetInstance(c.Kernel)); 

    Vous obtiendrez le comportement souhaité, à savoir ne pas avoir de constructeur public mais permettre à votre façade d’être injectée efficacement.

  2. Effectuer l’injection chaque fois que l’ instance ISingleton est demandée

    Si pour une raison quelconque vous n’êtes pas autorisé à modifier votre ConcreteSingleton : Cette approche encapsulera la création d’un singleton dans un fournisseur pour injecter efficacement l’instance uniquement pour la première fois qu’elle est créée. Il est important de noter que le fournisseur lui-même doit être enregistré en tant que singleton.

     internal class ConcreteSingletonProvider : Provider { public IKernel Kernel { get; set; } //Just a wrapper private readonly Lazy _lazy = new Lazy(() => ConcreteSingleton.Instance); public ConcreteSingletonProvider(IKernel kernel) { Kernel = kernel; } protected override ISingleton CreateInstance(IContext context) { if (_lazy.IsValueCreated == false) { Kernel.Inject(ConcreteSingleton.Instance); } return _lazy.Value; } } 

    Et vos liaisons devraient être comme ça:

     kernel.Bind().ToProvider(); kernel.Bind().ToSelf().InSingletonScope(); 

    Cet essentiel a un échantillon de travail complet pour l’approche ci-dessus.

J’espère que cela pourra aider!