unity net inyección inyeccion framework desventajas dependencias control asp c# dependency-injection inversion-of-control

c# - net - inyeccion de dependencias php



Inyección de dependencia: nueva instancia requerida en varios de los métodos de una clase (5)

Tengo un código que se parece a esto:

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 interna. Necesito crear una nueva instancia de él en cada llamada de 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 llamaría al contenedor en todos y cada uno de los métodos? ¿O hay una manera más pulida donde solo puede hacer una llamada al contenedor?

¿Qué pasaría si no estuviera usando un contenedor IoC? ¿Habría una manera de no crear una instancia concreta en cada método?


La mayoría de las respuestas aquí hasta ahora sugieren que cambie el tipo de dependencia inyectada a algún tipo de Abstract Factory (un Func<T> también es un Abstract Factory) para solucionar el problema. Sin embargo, si lo hace, sería una abstracción permeable porque permitiría que el conocimiento de una implementación particular determinara 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 una envoltura para la IDependencia que aborde el problema particular de la vida:

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 un Abstract Factory en este nivel.


Las dos primeras ideas que me vienen a la cabeza son:

  1. No lo tome en el constructor, sino en cada método.
  2. En lugar de pasar una instancia al constructor, pase una fábrica o una Func<IDependency> que creará una nueva instancia cada vez que llame a la función.

Parece que debes inyectar un proveedor / fábrica. La forma en que lo represente depende de usted (y de lo que admita su IoC) - podría ser tan simple como:

public MyService(Func<IDependency> 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<T> genérico IFactory<T> etc. Hay todo tipo de posibilidades, pero el bit central es que inyecta lo que necesita, que en este caso es "un IDependency de crear una nueva implementación de la IDependency de IDependency en cada llamada ".


Podrías hacerlo así:

private readonly Func<IDependancy> _dependancy; public MyService(Func<IDependancy> 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();


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

interface IDependencyFactory { IDependency GetInstance(); }