370 votes

Ce qui ' la différence entre les modèles Injection de dépendance et le localisateur de Service ?

Les deux modèles semblent comme la mise en œuvre du principe de l'inversion de contrôle. C'est, qu'un objet ne doit pas savoir construire ses dépendances.

L'Injection de dépendance (DI) semble utiliser un constructeur ou un setter pour "injecter" ses dépendances.

Exemple d'utilisation du Constructeur d'Injection:

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

Service de Localisation semble utiliser un "conteneur", qui relie ses dépendances et donne foo c'est un bar.

Exemple d'utilisation d'un Localisateur de Service:

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo()
  {
    this.bar = Container.Get<IBar>();
  }

  //...
}

Parce que nos dépendances sont juste des objets eux-mêmes, ces dépendances les dépendances, qui ont même plus les dépendances, et ainsi de suite et ainsi de suite. Ainsi, l'Inversion de Contrôle du Conteneur (ou DI Containor) était né. Exemples: Château de Windsor, Ninject, la Structure de la Carte, Printemps, etc.)

Mais un CIO/DI Conteneur ressemble exactement comme un Localisateur de Service. Est de l'appeler une DI Containor un mauvais nom? CIO/DI Conteneur juste un autre type de Service Locator? Est la nuance dans le fait que nous utilisons DI Conteneurs surtout lorsque nous avons beaucoup de Dépendances?

241voto

tvanfosson Points 268301

La différence peut sembler minime, mais même avec le ServiceLocator, la classe est toujours responsable de la création de ses dépendances. Il utilise juste le localisateur de service pour le faire. Avec DI, la classe est compte tenu de ses dépendances. Il ne sait pas ni ne se soucie d'où ils viennent. Un résultat important est que les DI exemple est beaucoup plus facile de test de l'unité -- parce que vous pouvez passer maquette implémentations de ses objets dépendants. Vous pouvez combiner les deux et injecter le service locator (ou une usine), si vous vouliez.

118voto

Joel Points 3356

Lorsque vous utilisez un localisateur de service, chaque classe aura une dépendance à votre service locator. Ce n'est pas le cas avec l'injection de dépendance. La dépendance de l'injecteur sera généralement appelé une seule fois au démarrage d'injecter des dépendances dans certaines classe principale. Les classes de cette classe dépend de la volonté de manière récursive ont leurs dépendances injecté, jusqu'à ce que vous avez un objet graphique.

Une bonne comparaison: http://martinfowler.com/articles/injection.html

Si votre dépendance à l'injecteur ressemble à un localisateur de service, où les classes d'appel de l'injecteur directement, il n'est probablement pas une dépendance de l'injecteur, mais plutôt un localisateur de service.

60voto

Jeff Sternal Points 30147

Service localisateurs de cacher ses dépendances, - vous ne pouvez pas dire en regardant un objet qu'il frappe une base de données ou pas (par exemple) lorsqu'il obtient des connexions à partir d'un localisateur. Avec l'injection de dépendance (au moins constructeur injection) les dépendances sont explicites.

En outre, le service de localisateurs de briser l'encapsulation, car ils fournissent un point d'accès pour les dépendances d'autres objets. Avec le service de localisation, comme avec tout singleton:

il devient difficile de préciser les pré et post conditions pour le client de l'objet l'interface, parce que le fonctionnement de ses la mise en œuvre peut être touché à partir de l'extérieur.

Avec l'injection de dépendance, une fois les dépendances d'un objet sont spécifiés, ils sont sous le contrôle de l'objet lui-même.

57voto

Nathan Points 1427

*Martin Fowler état*s: "Avec le service localisateur de la classe d'application le demande explicitement par un message à la localisation. Avec l'injection il n'y a pas de demande explicite, le service s'affiche dans la classe d'application – d'où l'inversion de contrôle."

En bref: Service Locator et l'Injection de Dépendance sont juste des implémentations de l'Inversion de Dépendance Principe.

Le principe important est "Dépendent des Abstractions, non pas sur des Concrétions". Cela rendra votre logiciel de conception de "couplage lâche", "extensible", "flexible".

Vous pouvez utiliser celui qui correspond le mieux à vos besoins. Pour une grosse application, avoir une énorme base de code, vous feriez mieux d'utiliser un Localisateur de Service, parce que l'Injection de Dépendance aurait besoin de plus de modifications à votre base de code.

Vous pouvez consulter ce post: Inversion de la Dépendance: Localisateur de Service ou de l'Injection de Dépendance

Aussi le classique: l'Inversion de Contrôle des Conteneurs et l'Injection de Dépendance motif par Martin Fowler

La conception des Classes Réutilisables par Ralph E. Johnson & Brian Foote

Toutefois, celui qui a ouvert mes yeux était: ASP.NET MVC: Résoudre ou à Injecter? C'est la Question... par Dino Esposito

28voto

Grant Palin Points 3459

Une classe à l'aide du constructeur DI indique la consommation de code qu'il y a des dépendances à satisfaire. Si la classe utilise la SL en interne pour récupérer ces dépendances, la consommation de code n'est pas au courant des dépendances. Ce mai sur la surface semble mieux, mais il est effectivement utile de savoir de toutes les dépendances explicites. Il est préférable de partir d'une vue architectural. Et quand vous faites le test, vous devez savoir si une classe a besoin de certaines dépendances, et de configurer le SL à fournir des mesures de fausses versions de ces dépendances. Avec DI, il suffit de passer dans le faux. Pas une énorme différence, mais il est là.

DI et SL peuvent travailler ensemble, cependant. Il est utile de disposer d'un emplacement central pour la commune de dépendances (par exemple, paramètres, enregistreur, etc). Étant donné une classe à l'aide de ces deps, vous pouvez créer un "vrai" constructeur qui reçoit le deps, et une valeur par défaut (sans paramètre) constructeur qui récupère de la SL et la transmet à la "vrai" constructeur.

EDIT: et, bien sûr, lorsque vous utilisez la SL, vous êtes l'introduction de certains de couplage de l'élément. Ce qui est ironique, puisque l'idée d'une telle fonctionnalité est d'encourager les abstractions et de réduire le couplage. Les préoccupations peuvent être équilibré, et il dépend de la façon dont de nombreux endroits, vous devez utiliser le SL. Si, tel que suggéré ci-dessus, juste par défaut dans le constructeur de la classe.

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