12
votes

Quel rôle les délégués jouent-ils dans une injection de dépendance?

Dans la plupart des exemples d'injection de dépendance, je vois des objets simples étant injectés, tels que dans l'exemple ci-dessous SecurityManager est injecté dans MainApplication .

Cependant, il semblerait naturel d'injecter délégués aussi, comme dans l'exemple ci-dessous, comme dans l'exemple ci-dessous Loghandler est injecté dans MainApplication .

Les délégués ne sont généralement pas utilisés dans une injection de dépendance? Quelles seraient des raisons et contre leur utilisation? xxx


1 commentaires

Pour autant que je puisse voir une injection de dépendance, des personnes qui utilisent principalement Java, qui n'a aucun délégué / rappel, et au début, ce n'était qu'un outil de traitement de cette invalidité.


3 Réponses :


2
votes

Je sais que MEF par exemple permet d'injecter des délégués. Cependant, vous pouvez également faire une interface ILOG comportant une méthode de journal avec la même signature que votre délégué. Je pense que ce sera beaucoup plus clair de comprendre que l'intention était d'injecter une implémentation d'un objet capable de se connecter plutôt que d'une seule fonction de journalisation.


0 commentaires

5
votes

J'utilise occasionnellement des délégués comme interfaces anonymes - aussi pour DI.

Un problème avec cette approche, cependant, est qu'il devient un peu plus difficile à tester l'unité que la dépendance correcte a été injectée et utilisée dans une classe, car une instance déléguée n'est pas un type, et parfois vous Il suffit simplement de vérifier qu'une classe utilise le type de stratégie / dépendance correcte.


0 commentaires

4
votes

Retour aux principes orientés de l'objet, l'une des caractéristiques essentielles d'un objet est qu'elle a un comportement et état fort>. Je pourrais envisager un scénario dans lequel un gestionnaire de journal peut avoir besoin de maintenir une sorte d'état (logfilename, DB Connection, etc.), mais il pourrait également y avoir un argument pour un gestionnaire de journal qui n'a pas besoin de se préoccuper d'un état.

Si Votre dépendance doit gérer l'état à part entière, utiliser un objet approprié (plutôt une interface). P>

Si votre dépendance n'a que le comportement et non l'état, puis un délégué pourrait convenir, bien que certaines personnes puissent être plus à l'aise à l'aide d'un objet approprié (interface) de toute façon, comme il serait peut-être plus facile d'ajouter la gestion de l'État à celui-ci ultérieurement si nécessaire. P>

Un avantage des délégués est qu'ils sont fous simples à moquer avec des expressions Lambda :) (même si les interfaces sont assez faciles à moquer, aussi) P>

Bien sûr, tout délégué peut toujours être une méthode normale sur un objet normal et que cette méthode peut totalement avoir un comportement qui affecte l'état de l'objet, et il y a certainement des raisons valables de le faire, mais vous approchez du point que cela pourrait faire plus de sens juste pour prendre une dépendance sur l'objet entier, au lieu d'une seule de ses méthodes. P>

plus bas sur ce chemin, les délégués injectables peuvent également être un moyen d'appliquer principe de ségrégation d'interface , vous pouvez donc vous assurer que votre système ne dépend pas de choses qu'il n'utilise pas. P>

Une autre note sur les délégués ... h3>

Il n'y a presque jamais de bonne raison de définir votre propre type de délégué. La plupart des cas d'utilisation entrent dans le Func code> et action code> c # (et événements, mais c'est un autre problème). Dans votre cas, votre constructeur code> ne doit pas prendre un window1.loghandler code> en tant que paramètre, mais simplement une action action code>. Ensuite, vous venez d'appeler cela avec: p> xxx pré>

ou similaire, car la méthode consoleloghandler code> correspond déjà à l'action Code> Signature. p>

et dans votre test, vous l'insentiez simplement avec: p> xxx pré>

ou même mieux: p>

int timesCalled;
MainApplication app = new MainApplication(x => { timesCalled++ }, new MySecurityManagerStub());


1 commentaires

+1 Bonne réponse, mais je pense que je dois être en désaccord avec votre dernière note concernant la préférence action au lieu d'un délégué nommé dans le cas où vous rencontrez le délégué dans le constructeur. Public MainApplication (Loghandler Loghandler) est plus clair que Public MainApplication (Action Connexion) . Il vous permet également (théoriquement, en fonction de la mise en œuvre du conteneur DI) pour enregistrer Connexion explicitement comme une dépendance, car vous ne pouvez pas simplement enregistrer action dans un conteneur di Comme cela serait ambigu (vous pourriez avoir d'autres utilisations pour action ).