2013-01-11 8 views
1

Je suis nouveau avec Ninject. Quelqu'un peut-il m'aider à réaliser ce que je veux. Je vais vous donner mon exemple. S'il vous plaît aidez-moi comment vous utilisez NInject pour obtenir un couplage lâche.Comment réaliser un couplage lâche avec Ninject

Disons que j'ai une interface donnée ci-dessous.

public interface IVehicle 
{ 
PrintSpecification(); 
} 

Maintenant j'ai trois classes implémentant l'interface ci-dessus. Ils pourraient être comme montré.

public class Car implements IVehicle 
{  
public void PrintSpecification() 
{ Console.WriteLine("Specification for Car");} 
} 

public class Bus implements IVehicle 
{ 
    public void PrintSpecification() 
    { Console.WriteLine("Specification for Bus");} 
} 

public class Truck implements IVehicle 
{ 
    public void PrintSpecification() 
    { Console.WriteLine("Specification for Truck");} 
} 

Maintenant dans mon programme principal, je vais avoir quelque chose comme ça. Ici, j'ai utilisé un nouvel opérateur pour créer trois implémentations concrètes de Car, Bus et Truck. Je dois afficher les spécifications des trois véhicules. Maintenant je me demande comment j'écris mes codes Ninject pour qu'il n'y ait pas de dépendance des classes concrètes.

Public static void main() 
{ 
    IVehicle v1=new Car(); 
    IVehicle v2=new Bus(); 
    IVehicle v3=new Truck(); 
    v1.PrintSpecification(); 
    v2.PrintSpecification(); 
    v3.PrintSpecification(); 
} 
+0

réponse est: cela dépend de la façon dont vous le choix entre les différentes mise en œuvre dans votre application ... –

Répondre

1

Créer module avec des liaisons nommées pour IVehicle mises en œuvre:

public class AutoModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IVehicle>().To<Car>().Named("Small"); 
     Bind<IVehicle>().To<Bus>().Named("Big"); 
     Bind<IVehicle>().To<Truck>().Named("Huge"); 
    } 
} 

et obtenir vos véhicules par nom:

IKernel kernel = new StandardKernel(new AutoModule()); 
IVehicle v1 = kernel.Get<IVehicle>("Small"); 
IVehicle v2 = kernel.Get<IVehicle>("Huge"); 
IVehicle v3 = kernel.Get<IVehicle>("Big"); 
v1.PrintSpecification(); 
v2.PrintSpecification(); 
v3.PrintSpecification(); 
+0

Est-ce la bonne façon de câblage des méthodes concrètes ou vous venez de donner l'alternative. De plus, si j'ai 50 autres types d'interfaces à câbler, devrais-je le faire avec la même méthode de chargement. – user1592389

+0

@ user1592389 Oui, vous devez lier tous les types dont vous avez besoin pour votre application. De même, si vous devez lier un type à différentes implémentations, vous devez utiliser la liaison nommée. –

+1

@lazyberezovsky La liaison nommée n'est pas le seul moyen ... cela dépend de ce que vous voulez réaliser. –

2

Vous pouvez lier toutes les spécifications de cette façon:

public class AutoModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IVehicle>().To<Car>(); 
     Bind<IVehicle>().To<Bus>(); 
     Bind<IVehicle>().To<Truck>(); 
    } 
} 

et dans votre application:

IKernel kernel = new StandardKernel(new AutoModule()); 

kernel.Bind<Inspector>().ToSelf(); 

class Inspector 
{ 
     IVehicle[] vehicles; 
     public Inspector(IVehicle[] vehicles) 
     { 
      this.vehicles=vehicles; 
     } 
     public void PrintSpecifications() 
     { 
      foreach(var v in vehicles) 
      { 
       v.PrintSpecification(); 
      } 
     } 
} 

//automatic injection in constructor 
kernel.Get<Inspector>().PrintSpecifications(); 

Si vous voulez un moyen de lier conditionately une implémentation vous pouvez utiliser

  • nommé Manchettes
  • Fixations conditionnelles
  • Manchettes contextuels

There is a good documentation inthe NInject wiki.

Si vous avez besoin de mapper plusieurs tyes dans votre module, envisagez d'utiliser une convention de nommage et de créer des stratégies de liaison automatique.

Vous devriez également faire quelques efforts pour être découplé du conteneur IoC aussi, regardez comment fonctionne le Composition Root Pattern.

+0

merci pour votre réponse. J'ai une dernière question conceptuelle cependant. Avec votre solution, au lieu de créer concrètement Car, Bus et Camion dans ma méthode Main, je les ai créés dans la méthode Load() du module.Maintenant, ma question est de savoir comment avoir ces classes dans la méthode Load() l'a rendu faiblement couplé puisque je dois encore spécifier des noms de classes concrets quelque part. – user1592389

+0

La seule chose que je n'utilise pas cette fois est "nouveau" opérateur. Cela ne rend pas AutoModule étroitement couplé avec des classes concrètes. – user1592389

+0

@ user1592389 le module est autorisé à être couplé car il contient les types qu'il veut exposer. L'important est que votre application soit découplée avec le module. Je vous suggère de vous découpler de l'IoC aussi. –

Questions connexes