6
votes

La château de Windsor peut-elle être utilisée pour implémenter IDEPendencyResolver dans ASP.NET MVC 4?

J'ai lu Cet article et a vu Beaucoup de gens ont commenté que N'utilisez pas de château Windsor pour mettre en œuvre IDEPendencyResolver dans ASP.NET MVC3 et coller avec une personnalisation IcontrollerFactory. Fondamentalement, mes questions sont maintenant:

  1. N'utilisez pas de château Windsor pour mettre en œuvre IDEPendencyResolver. Est-ce toujours vrai dans asp.net mvc 4 ?

  2. Si 1 est le cas. Un autre conteneur di (Unity, Structuremap peut-il avoir le même problème que le château Windsor? Puis-je utiliser une alternative?

    Merci beaucoup

    Modifier

    Cela me semble que le château Windsor ne doit pas être utilisé pour implémenter idependencyResolver . J'ai décidé d'utiliser un autre conteneur di, tel que StructureMap


1 commentaires

@ Sean717, avez-vous lu des commentaires dans votre lien à l'intérieur de la question?


3 Réponses :


4
votes

Il n'y a pas de différence entre MVC3 et MVC4 en ce qui concerne IDEPendencyResolver, autre que le fait qu'il existe un résolveur séparé pour webapi.

À mon avis, Mike Hadlow est un peu trop caustique sur ce sujet et de nombreuses autres personnes ont sauté sur le train sans vraiment envisager pourquoi.

Oui, il est vrai que le château Windsor possède un style de vie d'objet spécifique (objet de gestion de la vie à vie) appelé groupé qui vous oblige souvent à appeler la libération. Et lors de l'utilisation de ce style de vie, vous ne devez probablement pas utiliser IDEPendencyResolver, car il ne donne pas accès à cette méthode de sortie (bien qu'il y ait des moyens autour de cela).

Cependant, je pense qu'il est généralement mauvais d'utiliser ce style de vie dans une application Web, et vous devez plutôt utiliser le style de vie Perwebrequest, qui libérera automatiquement des objets à la fin de la demande Web. Si tel est ce que vous utilisez, il n'y a aucun problème à utiliser IDEPendencyResolver avec château Windsor.

Pourquoi je pense que Hadlow est trop caustique? Eh bien, parce qu'il basse tout son argument à ce sujet:

"C'est vrai, pas de méthode" libération ". Vous pouvez fournir un service de votre conteneur COI, mais il n'y a aucun moyen de le nettoyer. Si j'allais utiliser cela dans la boutique STEUTEKI, j'aurais une fuite de mémoire de proportions épiques. "

Il poursuit ensuite l'article de Krzysztof Koźmic concernant la gestion de mode de vie, mais néglige de faire référence à son article de suivi que je ferai ici:

http://kozmic.net / 2010/08/27 / Must-i-Livraison - tout-en utilisant-windsor /

Notez ce qu'il dit ici:

"Depuis que j'ai mentionné dans mon post précédent, Windsor suivra votre composant, C'est une idée fausse commune détenue par les utilisateurs que pour libérer correctement tous les composants qu'ils doivent méthode de sortie d'appel sur le conteneur. "

Il continue à parler de divers autres aspects également, mais en général, je ne pense pas que la plupart des gens utiliseront des objets regroupés ou transitoires nécessitant une élimination d'une application Web. Et si vous faites, alors vous devez savoir ne pas utiliser IDEPendencyResolver alors. Sinon, vous ne devriez avoir aucun problème.

Je sais que je vais probablement avoir beaucoup de chagrin des gens qui se disputent autrement, mais je ne vois tout simplement pas cela comme la fin de la question mondiale que les personnes comme Hadlow semblent penser que c'est, puisqu'il y a tellement d'alternatives, et les échelonnements même lorsque vous devez appeler la libération.

Outre tout cela, en utilisant un style de vie qui nécessite une sortie d'appel, c'est un travail supplémentaire pour vous, le développeur. Vous devez maintenant gérer la durée de vie des objets et n'oubliez pas de disposer d'objets et de ne pas le faire, crée des fuites de mémoire. Ceci est essentiellement annulant les avantages de la collecte des ordures à mon avis. J'utilise seulement des objets transitoires avec des choses qui n'ont pas besoin de disposition et je n'utilise jamais d'objets potables.

Au fait, je me trompe peut-être, mais je ne pense pas que aucun autre conteneur ait ce problème. Cela me conduit à la conclusion que c'est Windsor qui est cassé, plutôt que MVC, lorsque tous les autres conteneurs ne semble pas avoir de problème avec cela. Windsor aime rester obstinément à sa version de la réalité, donc ymmv.


2 commentaires

«Je ne pense pas que la plupart des gens utiliseront des objets groupés ou transitoires qui nécessitaient une élimination dans une application Web» - Eh bien, j'ai utilisé un objet transitoire et je devais apprendre cette leçon de manière très difficile. Donc je m'enlève toujours avec IcontrollerFactory


@Meixger - Pouvez-vous expliquer pourquoi vous avez besoin d'un objet de vie qui a besoin d'être disposé plus rapidement que l'étendue d'une demande Web?



3
votes

Le conseil de ne pas utiliser idependencyResolver est stupide, car il peut être utilisé avec le château Windsor, même si l'interface n'a pas de méthode de libération. La solution consiste simplement à laisser le cache idependencyresolver chaque instance demandée (dans un cache limitée sur la demande Web, à l'aide de httpcontext.items par exemple). À la fin de la demande, toutes les instances en cache (généralement quelques-uns) peuvent être libérées.

Pour pouvoir libérer toutes les instances à la fin de la demande Web, vous devez enregistrer un événement request_ends dans le global.asax ou enregistrez un httpmodule qui fait cette.

Vous pouvez appeler cela une solution de contournement, mais pas utiliser le idependencyResolver n'est pas vraiment une option, car elle est trop profondément intégrée à MVC. En outre, d'autres conteneurs (tels que l'injecteur NInject et simple) utilisent cette même approche (à l'aide d'une option httpmodule) pour «libérer» des instances.

Il est malheureux cependant qu'il n'y a pas de packages de nuge officiels pour Omtegrativement Windsor avec MVC, car vous devrez maintenant la mettre en œuvre vous-même. Tous les autres cadres ont un tel paquet BTW. Mais encore une fois, ce n'est pas si difficile de mettre en œuvre cela vous-même.

D'autres conteneurs de CIO montrent déjà qu'il est possible de mettre en œuvre la libération comme détail de mise en œuvre et que vous n'avez pas besoin de version dans le cadre du contrat IDEPendencyResolver . Les designers MVC ont réellement fait la bonne chose en supprimant une telle méthode de l'API.


0 commentaires

2
votes

Pendant que je suis d'accord sur la mise en œuvre d'IDEPendencyResolver est possible et non terriblement difficile .. Et oui, selon les modes de vie en jeu, libérer explicitement () 'Ing peut-être pas d'importance ... et oui, il existe des moyens de forcer une libération () En mettant en cache l'instance quelque part ainsi que d'autres astuces subtiles - je pense que c'est beaucoup à laisser à interprétation et peut être problématique et difficile à suivre. Comprendre quand Windsor va suivre une instance n'est pas toujours immédiatement évidente (c'est-à-dire si le composant a des préoccupations de déclassement vs non, de style de vie, etc.). L'une des principales valeur ajoutée du CIO est de centraliser la responsabilité de la création d'objets et de la gestion des instances. Pour le faire correctement et avoir la séparation des préoccupations - vous devez avoir une architecture que vous pouvez avoir confiance vous servira bien dans des scénarios d'appel et que l'OMI signifie avoir une réponse de report de fer à relâcher () 'ING ING de toutes les saveurs. Mon conseil est de toujours mettre en œuvre une conception qui permettra la libération d'être appelée - en particulier sur les racines (c'est-à-dire un contrôleur).

L'argument final contre IDEPendencyResolver Vous devez enregistrer un certain nombre de composants du système MVC si vous intégrez à ce niveau. C'est trop intime d'une danse entre mon application et le cadre situé sous mon goût. IcontrollerFactory donne un point d'intégration beaucoup plus ciblé, vous n'avez pas à enregistrer des composants système MVC et vous obtenez un crochet de libération (). Ainsi, sauf si vous souhaitez remplacer les composants du système MVC, je vois très peu de raisons de mettre en œuvre IDEPENDENCENDENSOLVER sur icontrollerFactory. Je vois en fait l'argument opposé. Personnellement, je me suis heurté à cela sur ce Le fil ici montre à la fois des approches.

J'espère que cela aide


6 commentaires

Cet argument se contredit. S'il est si important que le conteneur soit responsable de la libération, pourquoi vous oblige-t-il à le dire quand libérer? Évidemment, cet argument est défectueux, car vous dépendez toujours de l'application pour contrôler quand cela se produit et non le conteneur. Cet argument ignore également le fait que IdependencyResolver est utilisé pour beaucoup plus que des contrôleurs d'instanciation, et l'utilisation d'un icontrollerFactory personnalisé ne résout pas ces problèmes. Vous devez donc maintenant mettre en œuvre d'autres points d'extension.


Tigre facile ... Je n'ai pas écrit Windsor. Je vous dis juste comment travailler mieux avec cela en fonction de mes expériences et de beaucoup de lecture. Sa fonction de suivi est controversée, mais j'aimerais aimer cela après avoir pris le temps de le comprendre. Si vous sortez comme Windsor, il y a beaucoup d'autres conteneurs là-bas. Oh, et j'ai expliqué clairement que IdependencyResolver n'est nécessaire que IIIIIIIIIIFS, vous ne voulez pas remplacer les composants du système MVC.


Non, je crois que vous vous propageez sans doute le mythe que IdependencyResolver est cassé, malgré de nombreuses preuves au contraire. Même Krzysztof dit que l'idée d'appeler la libération sur tout est une idée fausse. Il dit que le point vide "Vous n'avez jamais besoin d'appeler la libération" si votre application est bien conçue. Mon point est que l'argument des personnes en faveur de l'ignorance de l'utilisation d'IDEPendencyResolver est auto-vaincable et illogique. Il dit que le conteneur doit être responsable de la durée de vie de l'objet, mais dit également que la durée de vie doit être contrôlée de manière externe en appelant la libération.


Je discutais également contre votre commentaire selon lequel l'utilisation d'IDEPendencyResolver nécessite d'enregistrer des choses "trop ​​nombreuses" .. Ce qui n'a pas de sens, car si vous n'utilisez pas IDEPendencyResolver, vous devez également enregistrer plusieurs choses aussi pour obtenir les avantages complètes, tels qu'un filtre fournisseur qui utilise le conteneur (MVC utilise IDEPendencyResolver pour cela, vous devez donc le faire manuellement) et le liant de modèle par défaut (à nouveau, MVC utilisera l'IDR pour résoudre les modèles, si vous ne l'enregistrez pas, si vous ne l'enregistrez pas. fournir le vôtre pour obtenir la même fonctionnalité) et un certain nombre d'autres points d'extension.


Je suppose que vous parlez de cela: devlicio.us/blogs/krzysztof_kozmic/archive/2010/08/27/... Oui, si vous tirez depuis le conteneur, vous avez un problème de conception. Mais si vous utilisez un style de vie qui n'a pas d'événement final que le conteneur est au courant ... vous devez absolument le relâcher. Il est très facile de créer des fuites dans mon expérience et l'expérience des ~ 70 développeurs que je travaille avec. Je le vois quotidiennement dans des cas qui ne contenaient pas d'abus de conteneur. Il est beaucoup plus facile d'appeler la libération de mon expérience, mais faites ce que vous voulez faire.


Et je ne sais pas de quoi vous parlez de "car si vous n'utilisez pas IDEPendencyResolver, vous devez enregistrer plusieurs choses aussi bien pour obtenir les avantages complètes". 99% du temps, les gens le font pour que Windsor crée le contrôleur - ils ne se soucient pas de tout ce genre d'autre. Si vous implémentez IDEPendencyResolver pour que Windsor Créez des contrôleurs, vous devez enregistrer tout ce type d'autre ou vous obtiendrez une exception. Si vous voulez remplacer ce produit, alors oui ... IdependencyResolver est ce que vous voulez, mais pas si tout ce que vous vous souciez de contrôleurs.