2010-01-13 8 views
58

Je suis un débutant complet à ninjectQuelle est l'intention des modules Ninject?

J'ai à part le code tirais de quelqu'un d'autre et a trouvé plusieurs exemples de modules ninject - classes qui dérivent de Ninject.Modules.Module, et une méthode de charge qui contient la plupart des leur code.

Ces classes sont appelées en appelant la méthode LoadModule d'une instance de StandardKernel et en lui passant une instance de la classe de module. Peut-être qu'il me manque quelque chose d'évident ici, mais quel est l'avantage de ceci en créant simplement une vieille classe et en appelant sa méthode, ou peut-être une classe statique avec une méthode statique?

 

Répondre

61

Les modules Ninject sont des outils utilisés pour enregistrer les différents types avec le conteneur IoC. L'avantage est que ces modules sont ensuite conservés dans leurs propres classes. Cela vous permet de mettre différents niveaux/services dans leurs propres modules. Avoir plusieurs modules permet de séparer les problèmes, même à l'intérieur de votre conteneur Ioc. Le reste de vous questionne semble être plus sur IoC et DI dans son ensemble, et pas seulement sur Ninject. Oui, vous pouvez utiliser des objets Configuration statiques pour faire à peu près tout ce qu'un conteneur IoC fait. Les conteneurs IoC deviennent vraiment intéressants lorsque vous avez plusieurs hiérarchies de dépendances.

public interface IInterfaceA {} 
public interface IInterfaceB {} 
public interface IInterfaceC {} 

public class ClassA : IInterfaceA {} 

public class ClassB : IInterfaceB 
{ 
    public ClassB(IInterfaceA a){} 
} 

public class ClassC : IInterfaceC 
{ 
    public ClassC(IInterfaceB b){} 
} 

Class BuildingC est une douleur à ce stade, avec plusieurs profondeurs d'interfaces. Il est beaucoup plus facile de demander au noyau un IInterfaceC.

var newc = ApplicationScope.Kernel.Get<IInterfaceC>(); 
+1

LinqToSqlDataContextModule devrait étendre StandardModule? –

+1

@Mark Gibaud pas dans Ninject 2. StandardModule est parti et remplacé par NinjectMdule - http://github.com/enkari/ninject/tree/master/src/Ninject/Modules/ –

+1

C'est un bon exemple, mais qu'en est-il de la testabilité? J'entends constamment comment un conteneur DI/IoC peut m'aider avec la testabilité, mais j'ai du mal à trouver un vrai exemple qui montrerait que Ninject ne polluera pas mon code et facilitera aussi la testabilité. Y a-t-il des projets open source réels que je pourrais regarder pour avoir l'idée? –

9

Peut-être que je manque quelque chose évidente , mais quel est l'avantage de ce sur la simple création d'une plaine ancienne classe et appelant sa méthode, ou peut-être une classe statique avec une méthode statique ?

Oui, vous pouvez simplement appeler un groupe d'instructions Bind<X>().To<Z>() pour configurer les liaisons, sans module.

La différence est que si vous mettez ces déclarations dans un module puis:

  • IKernel.Load(IEnumerable<Assembly>) peut découvrir de façon dynamique ces modules à travers la réflexion et de les charger.
  • les liaisons sont logiquement regroupées sous un nom; vous pouvez utiliser ce nom pour les décharger à nouveau avec IKernel.Unload(string)
3

Peut-être que je suis absent quelque chose ici évident, mais quel est l'avantage de cette création sur juste une plaine ancienne classe et appelant sa méthode, ou peut-être un classe statique avec une méthode statique?

Pour nous, il est très facile d'ajouter des tests plus tard. Remplacer juste quelques liaisons avec des objets mockobjects et voila .....sur un code hérité sans DI qui a câblé "tout", il est presque impossible de commencer à insérer des cas de test sans quelques retouches. Avec une DI en place ET aussi longtemps qu'il a été utilisé correctement où le DI a tout câblé, il est très simple de le faire même sur un code hérité qui peut être très laid.

Dans de nombreux environnements DI, vous pouvez utiliser le module de production pour votre test avec un module de test qui remplace les liaisons spécifiques avec des objets mock (en laissant le reste du câblage en place). Il peut s'agir de tests système plus que de tests unitaires, mais j'ai tendance à préférer les tests de niveau supérieur au développeur moyen car il teste l'intégration entre les classes et c'est une excellente documentation pour quelqu'un qui rejoint le projet. de seulement des parties de la fonctionnalité) sans avoir à configurer un système entier).