Supposons que j'ai le Service
qui reçoit les dépendances via le constructeur mais doit également être initialisé avec des données personnalisées (contexte) avant de pouvoir être utilisé:
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;
}
Maintenant - les données de contexte ne sont pas connues à l'avance, donc je ne peux pas l'enregistrer en tant que dépendance et utiliser DI pour l'injecter dans le service
Voici à quoi ressemble un exemple de client:
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();
}
}
Comme vous pouvez le voir - il y a un couplage temporel et initialise les odeurs de code de méthode impliquées, car je dois d'abord appeler service.Initialize
pour pouvoir appeler service.DoSomething
et service.DoOtherThing
ensuite.
Quelles sont les autres approches dans lesquelles je peux éliminer ces problèmes?
Clarification supplémentaire du comportement:
Chaque instance du client doit avoir sa propre instance du service initialisée avec les données de contexte spécifiques du client. Ainsi, ces données de contexte ne sont pas statiques ou connues à l'avance, elles ne peuvent donc pas être injectées par DI dans le constructeur.