web-dev-qa-db-fra.com

Comment les paramètres de constructeur d'un contrôleur MVC sont-ils définis?

Comment la construction fonctionne-t-elle avec une injection de dépendance?

Avec le code suivant:

public class AdvancedSearchController : Controller
{
    private EmployeeController _employeeController;

    public AdvancedSearchController(EmployeeController employeeController)
    {
        _employeeController = employeeController;
    }

Quand et comment le code employeeController dans le code ci-dessus est-il défini ou transmis dans le constructeur? Comment cette magie arrive-t-elle?

2
Rodney

Il n'y a pas de magie à moins que vous envisagez injection de dépendance magie. Si vous creusez dans le code de démarrage/bootstrap de cette application, vous trouverez presque certainement un conteneur COI . Regardez dans global.asax.cs et suivez les chemins de votre gestionnaire d'événements de démarrage de l'application. Vous trouverez une inscription de composant/service là-bas quelque part. Parfois, il est juste dans le global.aSax, parfois il est stocké dans App_Start, parfois c'est à la racine, et parfois c'est ailleurs. C'est là, cependant.

Les dernières versions du navire ASP.NET avec injection de dépendance intégrée . Les dernières versions de MVC le mettent à utiliser .

Si vous utilisez un cadre plus ancien, il existe de nombreux conteneurs tiers. Quelques exemples:

Le principe est simple. Vous enregistrez un type concret comme une représentation active d'un contrat. (Le contrat est généralement une interface, mais pourrait également être un type concret.) Puis dans le code, vous vous référez toujours à des contrats. Le conteneur vous donne le type enregistré, mais vous n'avez pas à penser aux détails. Cela facilite l'échantillonnage des implémentations dans un seul et un seul endroit. Ce qui, à son tour, il est facile de faire des choses comme des morceaux de code test à l'aide d'objets simulables prévisibles par rapport à l'utilisation d'objets imprévisibles et complexes. Les objets complexes rendent difficile la compréhension de ce que vous testez vraiment.

En plus des types d'enregistrement en tant que contrats, les conteneurs de la COI font également des choses fantaisistes telles que les types d'injection automatiquement dans des composants gérés. C'est ce que vous voyez dans votre exemple. Le conteneur gère vos contrôleurs. Il sait donc fournir un EmployeeController à votre AdvancedSearchController. Qui sait? Peut-être que cela a injecté un autre type dans le EmployeeController avant de le passer. (Vous n'avez pas demandé, mais je ne suis pas fou de réussir les contrôleurs. Si vous avez un mot à dire dans la matière, fossé-le. Remplacez-le avec un non-contrôleur qui fait le travail nécessaire. Les contrôleurs ne doivent que tricoter des modèles à des vues .)

Certains conteneurs vous permettent également de décider de la durée de vie de vos types enregistrés - peut-être qu'ils sont instanciés à chaque fois qu'ils sont utilisés, peut-être qu'un objet colle autour de la durée d'une demande Web (SLICK pour la gestion d'une unité de travail dans un Service Web), ou peut-être qu'il n'y a jamais une seule.

7
Scant Roger

Si vous utilisez ASP.NET CORE MVC, c'est comment cela fonctionne: vous devez enregistrer vos types dans la méthode ConfigureServices de la classe STERTUP.CS. La méthode ConfigureServices est appelée par l'exécution et ajoutez des services au conteneur d'injection de dépendance. Si vous ne l'enregistrez pas ici, lorsque le contrôleur est appelé, cela donnera une erreur. Il va toujours construire mais retournera une erreur lorsque le contrôleur est initié par une personne allant à cette URL. Étant donné que votre objet est enregistré, c'est celui qui sera injecté dans le contrôleur.

Alors, pourquoi est-ce utile? Votre classe STERTUP.CS devrait avoir quelque chose comme des services.AnddDTransient Iemplerecontroller, employeur de l'emploi (); Disons que vous vouliez utiliser de fausses données pour tester quelque chose. Vous modifieriez cette ligne à, services.addddTransient Iemplloirecontroller, employeurecontrollerfiledata ();

La classe EmployeeControllerFakedata aurait simplement des données codées durement que vous souhaitez tester. Puisque vous avez maintenant enregistré les employeursControllerfakedata qui est celui qui sera injecté dans le constructeur.

Vous prenez la dépendance dont il a besoin, que ce soit des données de test, des données Oracle, des données SQL, des données d'un fichier, etc. et de l'enregistrer, de sorte qu'elle soit injectée où elle est nécessaire.

0
Torres