2017-09-18 2 views
0

J'écris l'encapsuleur MVC UI en réutilisant les anciennes librairies de base qui ont été écrites pour l'édition de bureau en utilisant Autofac pour DI. Le problème auquel je suis confronté est, les bibliothèques de base travaillent avec la portée de vie que je ne peux pas changer pendant que MVC exige InstancePerRequest.Inconvénient de l'utilisation de ma propre Autofac LifetimeScope dans l'application MVC

Donc, dans MVC, si j'enregistre mes services pour la portée InstancePerRequest, ils sont éliminés par les bibliothèques de base avant la fin de la requête. Cela rend l'application MVC mécontente.
J'ai également essayé d'utiliser LifeTimeScope pour tous les services de l'application MVC. Comme la durée de vie est plus courte que la durée de vie de la requête, elle semble fonctionner dans MVC.

Y a-t-il un inconvénient dans cette approche?

Remarque: Dans le code hérité, tous les services de temps sont résolus manuellement, au lieu d'être injectés via le constructeur. Comme:

using (var scope = IocContainer.BeginLifetimeScope()) 
{ 
    var service = scope.Resolve<IMyService>(); 
    return service.FindAll(); 
} 

Répondre

0

MVC travaillera avec InstancePerLifetimeScope pour les services as noted in the documentation about sharing registrations across apps that have and apps that don't have request scopes.

Je pense qu'il y aura potentiellement deux pièges dans votre approche pour créer votre propre portée de vie. Si vous pouvez vivre avec eux est très spécifique à l'application, vous devrez donc juger par vous-même.

Problème 1: élimination précoce

Dans votre exemple, vous montrer une usine ou d'un service IMyService en cours de résolution, faire un peu de travail, et en retournant ce travail. À la fin de l'instruction using, l'étendue de la durée de vie propriétaire est supprimée. Cela signifie que IMyService sera éliminé (s'il s'agit de IDisposable) et que toutes les dépendances requises par IMyService seront également éliminées. Dans le cas de choses comme des contextes de base de données ou des connexions, cela pourrait signifier que la valeur de retour devient invalide parce que vous ne pourrez pas mettre à jour les valeurs ou lire des données supplémentaires par rapport à une connexion éliminée.

Problème 2: Singleton/Partage des questions

portées à vie sont parfois utilisés pour isoler les unités de travail ou des ensembles de composants qui ont besoin d'un contexte partagé. Par exemple, dans MVC, vous ne disposez que d'une seule instance du contrôleur pour toute la requête - quel que soit le nombre de fois que vous résolvez l'objet contrôleur, pour cette requête, il s'agira de la même instance. Vous pourriez voir une chose similaire avec les connexions à la base de données - une connexion du pool allouée pour toute une durée de vie de la requête. En créant votre propre portée à vie, vous créez également une sorte d'unité de travail logique. Les dépendances pour IMyService seront et non être partagées avec le reste de la demande MVC. En fait, c'est plutôt comme cette minuscule portée à vie est sa propre demande ou sa propre unité de travail. Pas de chevauchement.

Résolution générale

Comme il est indiqué dans le doc I linked to earlier, inscrivez-vous les choses comme InstancePerLifetimeScope si elles doivent être utilisés dans les deux contextes MVC et non-MVC et laisser la sémantique de demande MVC manipuler de rotation et l'élimination des champs si possible.

Si cela ne fonctionne pas, ce sera à vous et à votre code d'application de savoir si vous pouvez vivre avec les problèmes ici ou si vous avez besoin de les résoudre. Si vous avez besoin d'y répondre, cela sera également spécifique à l'application, donc il n'y a pas de «conseils» à fournir - vous êtes seul pour cela.