IoC - Prise en charge de plusieurs implémentations pour une seule interface
Je me demande pourquoi .Net Cio conteneurs ne sont pas facilement prendre en charge plusieurs implémentations d'une interface unique! Peut-être que je me trompe, mais j'en ai vu, des cadres comme Ninject prend partiellement en charge cette fonctionnalité à l'aide d'annotations (comment?). Je ne pense pas que d'autres cadres comme Windsor ou simple injecteur de disposer d'un mécanisme simple permettant à l'appui de ce scénario.
Est-il une raison pourquoi ce n'est pas pris en charge par de nombreux cadres? Autant que je sache, l'une des raisons les plus importantes pour utiliser des interfaces est de réaliser le couplage lâche. Si les cadres conçus pour améliorer le couplage lâche, ne sont pas couramment le soutien de plusieurs implémentations d'une interface unique, je ne comprends pas pourquoi!
P. S. bien sûr, je comprends qu'il y aura un problème de résolution au moment de l'exécution, et le conteneur de confusion dont la mise en œuvre de choisir, mais c'est quelque chose qui doit être considérée lors de la conception, à droite?
source d'informationauteur Bala
Vous devez vous connecter pour publier un commentaire.
L'unité a la même fonctionnalité
Registre nommé dépendance
Résoudre par nom
la même approche
Windsor a la même
Je le conseil à regarder Convention over Configuration et surtout Convention Basée sur l'Injection de Dépendance et contexte l'injection de dépendance. La plupart des Cio si tous ne prend en charge les deux approches. Vous pouvez trouver de nombreuses et intéressantes échantillons avec différentes Cio bibliothèques, lorsque plusieurs mise en œuvre se lier à une interface, et à quel point cela pouvait être.
Par exemple ninject prend en charge la liaison de plusieurs de la mise en œuvre d'une interface: dépend sur le contexte ou les attributs, par des noms, et donc un.
Par le contexte
L'extrait de code suivant lie sur la mise en œuvre dépend de type de cible automatiquement:
Par nom
Très utile lors de la configuration en XML ou de la base de données. Prendre en compte
InNamedScope
aussi:Par convention
Avec différents dépendance de configuration à différentes parties de votre projet.
Votre prémisse est fausse.
Windsor très heureux accepte que les enregistrements de plusieurs implémentations d'un même service. En plus du composant nommé en charge de la résolution mentionnée par GSerjo, à Windsor (par défaut), la première enregistré mise en œuvre va gagner, mais vous pouvez la remplacer en utilisant
IsDefault()
méthode lors de l'enregistrement d'une alternative de mise en œuvre. Veuillez voir http://docs.castleproject.org/Windsor.Registering-components-one-by-one.ashx pour plus de détails.Si vous souhaitez exercer plus de contrôle sur la sélection de plusieurs implémentations vous pouvez créer un IHandlerSelector mise en œuvre pour ce faire. Veuillez voir http://stw.castleproject.org/Windsor.Handler-Selectors.ashx pour plus de détails.
Mon conteneur Griffin.Conteneur prend en charge.
Et fetch:
Cependant, vous ne pouvez pas obtenir une mise en œuvre spécifique. C'est une décision de conception. Il est beaucoup mieux d'enregistrer une usine dans le conteneur, si vous avez pour obtenir une mise en œuvre spécifique. Lire plus ici dans la section consacrée aux meilleures pratiques.
Griffin.Le conteneur peut être trouvé sur github: https://github.com/jgauffin/griffin.container
StructureMap fournit ces capacités:
Votre question est un peu vague, puisque vous n'avez pas à fournir un exemple concret de quand vous pensez que vous avez besoin de cela. Dans la plupart des cas, il y a un problème dans votre application ou de design, ou que vous ne suivez pas DI meilleures pratiques.
Tous les conteneurs qui vous permettent d'enregistrer plusieurs dépendances avec la même interface que un
IEnumerable<ThatInterface>
même si elles n'ont pas de profondeur prise en charge de plusieurs instances. L'injection des listes de services dans d'autres services, cependant, est une conception de l'odorat, et il serait préférable de cacher cette liste derrière un Composite. Cela masque le fait qu'il existe plusieurs implémentations derrière l'abstraction, et vous permet de changer facilement le mode de fonctionnement des multiples implémentations sont utilisés, en changeant seulement un seul endroit dans l'application. Je ne crois pas que le Cio cadre a aucun support pour la génération de composites pour vous, car la il n'est pas un défaut de traitement de la enveloppé implémentations. Vous aurez à écrire ce Composite vous-même. Cependant, depuis la rédaction d'un tel composite est vraiment, vraiment simple, ce qui justifie de ne pas avoir cette fonctionnalité dans le cadre.Si vous voulez avoir plusieurs implémentations, mais toujours besoin de quelqu'un pour être retournée, sur la base de la configuration, il ya toujours des façons de le faire. La plupart des conteneurs qui vous permettent de configurer ces dépendances dans un fichier de configuration XML. Mais même si un conteneur ne contient pas de telle fonction, la lecture de cette valeur dans le fichier de configuration manuellement et l'enregistrement de ce type dans le récipient est très facile.
Si vous avez une mise en œuvre d'un certain interface pour la production et l'autre de mise en œuvre pour l'unité des fins de test, vous devez vous inscrire uniquement à la production de la mise en œuvre dans le conteneur. Vos tests unitaires doivent être dégagées de tout conteneur d'injection de dépendances, et vous devez manuellement créer une classe de test, et d'injecter de fausses dépendances dans son constructeur, il suffit de la
new
ing le type. À l'aide d'un conteneur d'injection de dépendances, pollue et complique vos tests. Pour y arriver, vous aurez besoin pour la conception de ce type autour de l'injection via le constructeur modèle. Ne pas appeler le conteneur (ou tout autre façade sur le conteneur) à l'intérieur du service sous test, pour récupérer les dépendances.