Bien, en primer lugar, tratemos con "Cualquier código que llame al ctor deberá actualizarse cuando se agreguen nuevas dependencias"; Para ser claros, si está haciendo una inyección de dependencia y tiene algún código que llama a new () en un objeto con dependencias, lo está haciendo mal .
Su contenedor DI debería ser capaz de inyectar todas las dependencias relevantes, por lo que no debe preocuparse por cambiar la firma del constructor, de modo que ese argumento realmente no sea válido.
En cuanto a la idea de inyección por método versus por clase, hay dos problemas principales con la inyección por método.
Un problema es que los métodos de su clase deben compartir dependencias, es una forma de ayudar a asegurarse de que sus clases estén separadas de manera efectiva, si ve una clase con una gran cantidad de dependencias (probablemente más de 4-5), entonces esa clase es un candidato principal para refactorizar en dos clases.
El siguiente problema es que para "inyectar" las dependencias, por método, tendría que pasarlas a la llamada al método. Esto significa que tendrá que resolver las dependencias antes de la llamada al método, por lo que probablemente terminará con un montón de código como este:
var someDependency = ServiceLocator.Resolve<ISomeDependency>();
var something = classBeingInjected.DoStuff(someDependency);
Ahora, supongamos que va a llamar a este método en 10 lugares alrededor de su aplicación: tendrá 10 de estos fragmentos. Luego, digamos que necesita agregar otra dependencia a DoStuff (): tendrá que cambiar ese fragmento 10 veces (o envolverlo en un método, en cuyo caso solo está replicando el comportamiento de DI manualmente, lo cual es un desperdicio de tiempo).
Entonces, lo que básicamente ha hecho allí es hacer que sus clases que utilizan DI sean conscientes de su propio contenedor de DI, lo cual es una idea fundamentalmente mala , ya que rápidamente conduce a un diseño torpe que es difícil de mantener.
Compare eso con la inyección del constructor; En la inyección de constructor, no está atado a un contenedor DI particular, y nunca es directamente responsable de cumplir con las dependencias de sus clases, por lo que el mantenimiento es bastante libre de dolor de cabeza.
Me parece que está tratando de aplicar IoC a una clase que contiene un montón de métodos auxiliares no relacionados, mientras que es mejor dividir la clase auxiliar en una serie de clases de servicio en función del uso, luego usar el auxiliar para delegar el llamadas. Esto todavía no es un gran enfoque (ayudante clasificado con métodos que hacen algo más complejo que solo lidiar con los argumentos que se les pasan, generalmente son solo clases de servicio mal escritas), pero al menos mantendrá su diseño un poco más limpio .
(Nota: he hecho el enfoque que estás sugiriendo antes, y fue una muy mala idea que no haya repetido desde entonces. Resulté que estaba tratando de separar las clases que realmente no necesitaban separarse, y terminé con un conjunto de interfaces donde cada llamada al método requería una selección casi fija de otras interfaces. Fue una pesadilla mantener).