Supongamos que tengo el Service
que recibe dependencias a través del constructor pero también necesita inicializarse con datos personalizados (contexto) antes de que pueda usarse:
public interface IService
{
void Initialize(Context context);
void DoSomething();
void DoOtherThing();
}
public class Service : IService
{
private readonly object dependency1;
private readonly object dependency2;
private readonly object dependency3;
public Service(
object dependency1,
object dependency2,
object dependency3)
{
this.dependency1 = dependency1 ?? throw new ArgumentNullException(nameof(dependency1));
this.dependency2 = dependency2 ?? throw new ArgumentNullException(nameof(dependency2));
this.dependency3 = dependency3 ?? throw new ArgumentNullException(nameof(dependency3));
}
public void Initialize(Context context)
{
// Initialize state based on context
// Heavy, long running operation
}
public void DoSomething()
{
// ...
}
public void DoOtherThing()
{
// ...
}
}
public class Context
{
public int Value1;
public string Value2;
public string Value3;
}
Ahora, los datos de contexto no se conocen de antemano, por lo que no puedo registrarlos como una dependencia y usar DI para inyectarlos en el servicio
Así es como se ve el cliente de ejemplo:
public class Client
{
private readonly IService service;
public Client(IService service)
{
this.service = service ?? throw new ArgumentNullException(nameof(service));
}
public void OnStartup()
{
service.Initialize(new Context
{
Value1 = 123,
Value2 = "my data",
Value3 = "abcd"
});
}
public void Execute()
{
service.DoSomething();
service.DoOtherThing();
}
}
Como puede ver, hay un acoplamiento temporal e inicialización de olores de código de método involucrados, porque primero necesito llamar service.Initialize
para poder llamar service.DoSomething
y service.DoOtherThing
luego.
¿Cuáles son los otros enfoques en los que puedo eliminar estos problemas?
Aclaración adicional del comportamiento:
Cada instancia del cliente debe tener su propia instancia del servicio inicializada con datos de contexto específicos del cliente. Por lo tanto, los datos de contexto no son estáticos ni se conocen de antemano, por lo que DI no puede inyectarlos en el constructor.