58 votes

Quelle est l'intention des modules Ninject ?

Je suis complètement novice en matière de ninject.

J'ai décortiqué le code de quelqu'un d'autre et j'ai trouvé plusieurs instances de modules nInject - des classes qui dérivent de Ninject.Modules.Module, et qui ont une méthode load qui contient la plupart de leur code.

Ces classes sont appelées en invoquant la méthode LoadModule d'une instance de StandardKernel et en lui passant une instance de la classe du module.

Peut-être que je rate quelque chose d'évident ici, mais quel est l'avantage de cette méthode par rapport à la création d'une simple classe et l'appel de sa méthode, ou peut-être une classe statique avec une méthode statique ?

61voto

Jarrett Meyer Points 11147

Les modules Ninject sont les 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 placer différents tiers/services dans leurs propres modules.

// some method early in your app's life cycle
public Kernel BuildKernel()
{
    var modules = new INinjectModule[] 
    {
        new LinqToSqlDataContextModule(), // just my L2S binding
        new WebModule(),
        new EventRegistrationModule()
    };
    return new StandardKernel(modules);
}

// in LinqToSqlDataContextModule.cs
public class LinqToSqlDataContextModule : NinjectModule
{
    public override void Load()
    {
        Bind<IRepository>().To<LinqToSqlRepository>();
    }
}

Le fait de disposer de plusieurs modules permet de séparer les préoccupations, même au sein de votre conteneur IoC.

Le reste de votre question semble concerner davantage IoC et DI dans leur ensemble, et pas seulement Ninject. Oui, vous pouvez utiliser des objets statiques de configuration pour faire à peu près tout ce que fait un conteneur IoC. Les conteneurs IoC deviennent vraiment intéressants lorsque vous avez de multiples 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){}
}

La construction de ClassC est un véritable calvaire à ce stade, avec de multiples profondeurs d'interfaces. Il est beaucoup plus facile de demander au noyau une IInterfaceC.

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

9voto

Wim Coenen Points 41940

Peut-être que je rate quelque chose d'évident ici, mais quel est l'avantage de ceci par rapport à la création d'une bonne vieille classe et d'appeler sa méthode, ou peut-être une classe statique avec une méthode statique ?

Oui, vous pouvez juste appeler un tas de Bind<X>().To<Z>() pour configurer les liaisons, sans module.

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

  • IKernel.Load(IEnumerable<Assembly>) peut découvrir dynamiquement de tels modules par réflexion et les charger.
  • les fixations sont logiquement regroupées sous un nom ; vous pouvez utiliser ce nom pour les décharger à nouveau avec la fonction IKernel.Unload(string)

3voto

Dean Hiller Points 5292

Peut-être que je rate quelque chose d'évident ici, mais quel est l'avantage de cette méthode par rapport à la création d'une simple classe et l'appel de sa méthode, ou peut-être une classe statique avec une méthode statique ?

Pour nous, c'est la possibilité d'ajouter des tests ultérieurement très facilement. Il suffit de remplacer quelques bindings par des mockobjects et voilà..... sur un code hérité sans DI qui relie "tout", il est presque impossible de commencer à insérer des cas de test sans retravailler. Avec un DI en place ET tant qu'il a été utilisé correctement où le DI a tout connecté, il est très simple de le faire même sur du code hérité qui peut être très laid.

Dans de nombreux frameworks DI, vous pouvez utiliser le module de production pour votre test avec un module de test qui remplace les liaisons spécifiques par des objets fantaisie (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 plus haut niveau que le développeur moyen, car ils permettent de tester l'intégration entre les classes et constituent une excellente documentation pour quelqu'un qui rejoint le projet et peut voir l'ensemble de la fonctionnalité en action (au lieu de seulement certaines parties de la fonctionnalité) sans avoir à configurer un système entier).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X