Nous avons un objet assez commun dans notre application. Dans ce cas, nous l'appellerons une balle. Les balles fonctionnent bien, mais dans certaines configurations, elles agissent différemment. Il est actuellement mis en place comme ceci:Objet couramment utilisé avec dépendance de la configuration
class Ball
{
private static readonly bool BallsCanExplode;
static Ball()
{
bool.TryParse(ConfigurationManager.AppSettings["ballsCanExplode"],
out BallsCanExplode);
}
public Ball(){}
}
Cela fonctionne très bien dans la pratique. Si la configuration est que les balles peuvent exploser, elles explosent, et sinon, non. Le problème est qu'il est complètement non testable. Je n'ai pas été en mesure de trouver un bon moyen de le garder testable, et encore facile à instancier.
La solution la plus simple est juste découpler la balle et la configuration:
class Ball
{
private readonly bool CanExplode;
public Ball(bool canExplode);
}
Le problème est que ce qui était autrefois une dépendance isolée dans la classe Ball est maintenant étendue à chaque classe qui fait Ballon. Si cela devient une dépendance injectée, alors la connaissance des boules qui explosent doit être injectée partout.
Le même problème existe avec une BallFactory. Alors que chaque classe peut simplement aller new Ball()
, il doit maintenant connaître une BallFactory qui doit être injectée partout. L'autre option est d'utiliser le service de localisation qui est déjà cuit à l'application:
class Ball
{
private readonly bool CanExplode;
public Ball()
{
CanExplode = ServiceLocator.Get<IConfiguration>().Get("ballsCanExplode");
}
}
Cela permet de maintenir encore la dépendance de configuration dans le ballon, mais permet une configuration de test à injecter dans Balls sont utilisés tant. cependant, que cela semble être trop difficile de localiser le service à chaque appel new Ball()
.
Quelle serait la meilleure façon de garder ce testable, ainsi que facile à instancier?
Remarque: Il existe à la fois un cadre d'injection de dépendances et un localisateur de service dans l'application, qui sont tous deux fréquemment utilisés.
Est-ce que ces D.I. bibliothèques comme l'aide de Ninject? – xandy
Vous semblez connaître les options d'injection de dépendance, mais vous ne voulez pas les suivre. Par conséquent, votre meilleure option est d'ajouter un constructeur pour tester: public Ball (bool CanExplode) –