Inyección de dependencia: nueva instancia requerida en varios métodos de clases

Tengo un código que se ve así:

public MyService(IDependency dependency) { _dependency = dependency; } public Message Method1() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); } public Message Method2() { _dependency.DoSomething(); } 

Ahora me acabo de dar cuenta de eso porque el objeto de dependencia contiene información de estado interno. Necesito actualizar una nueva instancia de este en cada llamada al método

Entonces, ¿cuál es la mejor manera de hacer esto y aún no tener una instancia concreta actualizada?

¿Usaría un contenedor IoC y haría una llamada al contenedor en todos y cada uno de los métodos? ¿O hay una forma más sencilla en la que solo puedes hacer una llamada al contenedor?

¿Qué ocurre si no estoy usando un contenedor IoC? ¿Habría alguna manera de no actualizar una instancia concreta en cada método?

La mayoría de las respuestas aquí hasta el momento sugieren que cambie el tipo de dependencia inyectado a algún tipo de fábrica abstracta (una Func también es una fábrica abstracta) para abordar el problema. Sin embargo, si lo hace, sería una abstracción con filtraciones porque permitiría que el conocimiento de una implementación en particular determine el diseño del consumidor. Esto viola el Principio de Sustitución de Liskov .

Una mejor opción es mantener MyService tal como está , y luego crear un contenedor para IDependency que resuelva el problema de por vida en particular:

 public class TransientDependencyWrapper : IDependency { public void DoSomething() { new MyStatefulDependency().DoSomething(); } } 

Inyecte eso en MyService en lugar de inyectar directamente la implementación original (MyStatefulDependency).

Si desea abstraer la creación de la dependencia, siempre puede inyectar una fábrica abstracta en este nivel.

Parece que deberías inyectar un proveedor / fábrica. Cómo lo representa depende de usted (y de lo que sea compatible con su IoC); podría ser tan simple como:

 public MyService(Func dependencyProvider) { this.dependencyProvider = dependencyProvider; } public Message Method1() { IDependency dependency = dependencyProvider(); dependency.DoSomething(); } 

… o podría tener una interfaz para este tipo de fábrica específico , o un IFactory genérico IFactory etc. Hay todo tipo de posibilidades, pero el núcleo es que se inyecta lo que necesita, que en este caso es “un forma de crear una nueva implementación de IDependency en cada llamada “.

Si necesita crear varias instancias de un tipo inyectado, debe inyectar una IDependencyFactory en IDependencyFactory lugar, que sería responsable de controlar los ciclos de vida de instancia:

 interface IDependencyFactory { IDependency GetInstance(); } 

Podrías hacerlo así:

 private readonly Func _dependancy; public MyService(Func dependancy) { _dependancy = dependancy; } public Message Method1() { _dependancy().DoSomething(); } public Message Method2() { _dependancy().DoSomething(); } public Message Method3() { _dependancy().DoSomething(); } 

Y entonces:

 var service = new MyService(() => new SomeConcreteDependency()); service.Method1(); service.Method2(); service.Method3(); 

Las dos primeras ideas que se me ocurren

  1. No lo tome en el constructor, pero síguelo en cada método.
  2. En lugar de pasar una instancia al constructor, Func una fábrica o Func que creará una nueva instancia cada vez que llame al func.