48

J'utilise ninject sur une nouvelle application web et il y a deux choses qui ne sont pas claires pour moi:NInject: Où gardez-vous votre référence au noyau?

  1. Ne ai-je besoin de garder une référence au noyau autour (Session/Variable App) à Assurez-vous que GC ne rassemble pas toutes mes instances? Par exemple, si je spécifie .Using() et que l'objet Kernel est collecté, tous mes "singletons" ne sont-ils pas également collectés?

  2. Si j'ai besoin de garder une référence à un objet noyau, comment puis-je permettre que les arguments passés à WithArguments() changent ou est-ce impossible?

Répondre

15

Il s'agit d'un piège courant lorsque vous commencez à utiliser un conteneur IoC. Voir this related question.

En bref:

  • Il est une mauvaise pratique pour passer votre conteneur autour (été là, fait cela, et ça fait vraiment mal)
  • Si vous avez vraiment besoin de invocate directement le récipient, d'abord considérer abstraire à une usine injectée, puis comme une dernière ressource envisager d'utiliser une passerelle statique vers le conteneur
+0

Je suis d'accord Je ne veux pas passer le conteneur, mais pourrais-je le stocker dans une variable Application par exemple? Mon problème est que chaque fois que je fais un nouveau StandardKernel (new CustomModule()), j'obtiens de nouvelles instances de tout. –

+0

Vous n'avez besoin que d'un seul StandardKernel par application. Si vous avez besoin de charger plusieurs modules, appelez simplement kernel.Load (new MyModule()); kernel.Load (nouveau AnotherModule()); etc –

+0

Ok, donc cela a du sens. Ce que je dois faire est de changer les arguments dans WithArguments() chaque fois que je demande un type ... est-il possible de le faire? En fin de compte ce que j'essaie de faire est d'implémenter un OnePerSessionBehavior et je veux que la liaison injecte les arguments actuels pour chaque session. –

29

Il est vrai que vous ne voulez pas faire circuler le noyau. En règle générale, dans une application Web, je stocke le noyau dans une propriété statique dans HttpApplication. Si vous avez besoin d'une référence au noyau, vous pouvez simplement exposer une dépendance (via l'argument constructeur ou la propriété) qui est du type IKernel, et Ninject vous donnera une référence au noyau qui a activé le type.

Si vous utilisez WithArguments() sur une liaison, ils seront utilisés pour toutes les activations. Si vous utilisez IParameters, ils ne seront utilisés que pour cette activation. (Toutefois, si le service que vous activez a un comportement réutilisable comme Singleton, il ne sera pas réactivé même si vous transmettez des IParameters différents.)

+0

Cela ressemble exactement à ce que je veux ... pouvez-vous poster du code pour cela? –

+0

@Nate: pas entièrement lié, mais avez-vous un ETA sur l'adaptateur CommonServiceLocator?Je vois qu'il y a un adaptateur sur la branche des expériences pour ninject2 ... –

+0

Salut @Nate, pouvez-vous poster le code source? –

-4

Mark Seeman - auteur de Manning Dependency Injection Suggestion d'utilisation Principe d'Hollywood Ne nous appelez pas (framework IOC) à la place Nous vous appellerons ... .. Le conteneur IOC doit être placé dans la racine Composition de l'application .. et il doit être instancié tel que demandé .. comme wat nate mentionné

.. Pour l'application Web, la racine de la composition est le fichier Global.asax où vous pouvez utiliser le remplacement des événements de démarrage et Vous pouvez lier votre Ninject pour résoudre le composant

+0

-1, principalement parce que la réponse est formulée d'une manière si floue et vague. En outre, la partie qui dit _ "il doit être instancié comme demandé" _ peut signifier vraiment n'importe quoi et n'est pas utile du tout. Cela étant dit, je serais certainement en faveur de ce qui est dit sur le "principe d'Hollywood" et la racine de la composition étant la seule chose qui devrait être récupérée directement à partir du conteneur DI. – stakx

+0

Cette réponse n'aide pas, car elle ne fait que répéter le contenu du lien. Vous n'avez pas dit ce que devrait être la racine de composition, alors vous pouvez simplement rayer les mots "Container IOC" et écrire "Composition Root" et c'est la même question ... –