Question

Dans la plupart des exemples que j'ai vus sur le Web, DI dans les contrôleurs MVC se fait comme ceci

public ProductController(IProductRepository Rep)
{
    this._rep = Rep;
}

Un ControllerFactory personnalisé est utilisé. Il utilise le framework de choix de DI et le référentiel est injecté.

Pourquoi ce qui précède est-il considéré comme meilleur que

public ProuctController()
{
    this._rep = ObjectFactory.GetInstance<IProductRepository>();
}

Cela donnera les mêmes résultats mais ne nécessitera pas de fabrique de contrôleurs personnalisés.

En ce qui concerne les tests, l’application de test peut avoir un BootStrapper séparé. Ainsi, lorsque les contrôleurs sont testés, ils peuvent obtenir les faux référentiels et s’ils sont réellement utilisés, ils en obtiendront également.

Était-ce utile?

La solution

L'injection de constructeur (la première approche) est meilleure que le modèle de localisateur de service (la seconde approche) pour plusieurs raisons.

Premièrement, le localisateur de services masque les dépendances. Dans votre deuxième exemple, qui concerne uniquement l'interface publique, il est impossible de savoir que ProductControllers a besoin de référentiels.

De plus, je dois faire écho à OdeToCode . Je pense

IProductRepository repository = Mockery.NewMock<IProductRepository>();
IProductController controller = new ProductController(repository);

est plus clair que

ObjectFactory.SetFactory(IProductRepository, new MockRepositoryFactory())
IProductController controller = new ProductController();

Surtout si ObjectFactory est configuré dans la méthode SetUp d'un appareil de test.

Enfin, le modèle de localisation de service est manifestement sous-optimal dans au moins un cas particulier: lorsque vous écrivez du code qui sera utilisé par des personnes écrivant des applications en dehors de votre contrôle. Je parie que les gens préfèrent généralement l'injection de constructeur (ou l'une des autres méthodes DI) car elle s'applique à tous les scénarios. Pourquoi ne pas utiliser la méthode qui couvre tous les cas?

(Martin Fowler propose une analyse beaucoup plus approfondie dans " Inversion des conteneurs de contrôle et modèle d'injection de dépendance " ; , en particulier la section "Service Locator vs Injection de dépendance").

Autres conseils

Le deuxième inconvénient du deuxième constructeur est que votre conteneur IoC doit être correctement configuré pour chaque test. Cette configuration peut devenir un véritable fardeau à mesure que la base de code se développe et que les scénarios de test deviennent plus variés. Les tests sont généralement plus faciles à lire et à gérer lorsque vous passez explicitement un double test.

Une autre préoccupation est de coupler un très grand nombre de classes à un framework DI / IoC spécifique. Bien sûr, il existe des moyens de le résumer, mais vous avez toujours du code jonché dans vos classes pour récupérer des dépendances. Étant donné que tous les bons frameworks peuvent déterminer les dépendances dont vous avez besoin en consultant le constructeur, vous perdez beaucoup d'efforts et de code en double.

Lorsque vous utilisez la deuxième approche, les inconvénients sont les suivants:

  • Des méthodes de configuration / contexte de test énormes et illisibles sont nécessaires
  • Le conteneur est couplé au contrôleur
  • Vous devrez écrire beaucoup plus de code

Pourquoi voulez-vous utiliser un conteneur ioc quand vous ne voulez pas d'injection de dépendance?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top