Bon, tout d'abord, parlons de "Tout code appelant le ctor devra être mis à jour lorsque de nouvelles dépendances seront ajoutées"; Pour être clair, si vous faites une injection de dépendance et que vous avez du code appelant new () sur un objet avec des dépendances, vous le faites mal .
Votre conteneur DI doit pouvoir injecter toutes les dépendances pertinentes, vous n'avez donc pas à vous soucier de changer la signature du constructeur, afin que cet argument ne tienne pas vraiment.
Quant à l'idée d'injection par méthode vs par classe, il y a deux problèmes majeurs avec l'injection par méthode.
Un problème est que les méthodes de votre classe doivent partager les dépendances, c'est une façon de vous assurer que vos classes sont séparées efficacement, si vous voyez une classe avec un grand nombre de dépendances (probablement plus de 4-5), alors cette classe est un candidat de choix pour refactoring en deux classes.
Le problème suivant est que pour «injecter» les dépendances, par méthode, vous devez les transmettre à l'appel de méthode. Cela signifie que vous devrez résoudre les dépendances avant l'appel de méthode, vous vous retrouverez donc probablement avec un tas de code comme celui-ci:
var someDependency = ServiceLocator.Resolve<ISomeDependency>();
var something = classBeingInjected.DoStuff(someDependency);
Maintenant, disons que vous allez appeler cette méthode à 10 endroits autour de votre application: vous aurez 10 de ces extraits. Ensuite, disons que vous devez ajouter une autre dépendance à DoStuff (): vous devrez modifier cet extrait 10 fois (ou l'encapsuler dans une méthode, auquel cas vous ne faites que répliquer le comportement DI manuellement, ce qui est un gaspillage de temps).
Donc, ce que vous avez fait là-bas, c'est que vos classes utilisant DI sont conscientes de leur propre conteneur DI, ce qui est fondamentalement une mauvaise idée , car cela conduit très rapidement à une conception maladroite difficile à maintenir.
Comparez cela à l'injection de constructeur; Dans l'injection de constructeur, vous n'êtes pas lié à un conteneur DI particulier, et vous n'êtes jamais directement responsable de remplir les dépendances de vos classes, donc la maintenance est assez sans maux de tête.
Il me semble que vous essayez d'appliquer IoC à une classe contenant un tas de méthodes d'assistance non liées, alors que vous feriez mieux de diviser la classe d'assistance en un certain nombre de classes de service en fonction de l'utilisation, puis d'utiliser l'aide pour déléguer la appels. Ce n'est toujours pas une excellente approche (une aide classée avec des méthodes qui font quelque chose de plus complexe que de simplement traiter les arguments qui leur sont transmis ne sont généralement que des classes de service mal écrites), mais cela gardera au moins votre conception un peu plus propre .
(NB j'ai fait l'approche que vous proposez avant, et c'était une très mauvaise idée que je n'ai pas répétée depuis. Il s'est avéré que j'essayais de séparer les classes qui n'avaient vraiment pas besoin d'être séparées, et j'ai fini par avec un ensemble d'interfaces où chaque appel de méthode nécessitait une sélection presque fixe d'autres interfaces. C'était un cauchemar à entretenir.)