J'essaie d'envelopper les contrôleurs d'API Web ( Appliquer des décorateurs aux contrôleurs est une astuce que j'applique avec succès aux contrôleurs MVC et j'aime évidemment faire la même chose dans l'API Web. P> J'ai créé une personnalisation Mon décorateur ressemble à ceci: p> Toutefois, quand j'exécute mon application et demande Le Impossible de lancer l'objet de type 'webapitest.myhttpcontrollerdecorator'
Tapez 'webapitest.controls.valuescontroller'. P>
blockquote> stacktrace: p> C'est comme si Web API nous fournit avec le Qu'est-ce que je fais mal? Comment puis-je décorer avec plaisir de mes contrôleurs API? P> P> IHTTPCONTROLLER CODE> Mises en œuvre) avec des décorateurs, mais lorsque je le fais, Web API jette une exception, car il s'agit en quelque sorte à la mise en œuvre réelle.
ihttpcontrolleractivator code> qui permet de résoudre la décoration
IHTTPCONTROLLER CODE> Mises en œuvre. Voici une implémentation dépourvée: p>
ValeursController Code>, Web API me jette le suivant
InvalidCastException CODE>: P>
iHttpcontroller code> abstraction mais dépend toujours de la mise en œuvre elle-même. Cela serait bien sûr une violation grave du principe d'inversion de dépendance et de rendre l'abstraction totalement inutile. Donc, je fais probablement quelque chose de mal à la place. P>
3 Réponses :
Je dirais que la voie naturelle et conçue comment réaliser ce comportement dans ASP.NET Web API est avec le gestionnaires de messages personnalisés / gestionnaires de délégation
Par exemple, j'ai ce et c'est comment injecter cela dans la structure: p> délégationHandler code> en place p> < Pré> xxx pré>
Merci pour votre réponse. Je suis toujours un peu ennuyé que je ne puisse pas décorer ihttpcontroller code>, mais votre solution satisfera probablement mes besoins :-). Le seul problème avec cette approche est que les gestionnaires de délégation sont des singletons et que certains ne peuvent pas dépendre d'un service avec une durée de vie plus courte. Existe-t-il un moyen de laisser les API Web les résoudre sur chaque demande?
Eh bien, parce que nous travaillons avec des services externes (pourraient être des singletons aussi) i> mais définir les valeurs dans le contexte (demande, httpcontext utilisateur) ... Nous n'avons pas besoin de l'instance par "demande". Le décorateur IHTTPCONTROLLER ne peut pas fonctionner, je dirais, car à la fin, nous ne travaillons pas avec cette interface. Le cadre examine (réflexion) le contrôleur "réel" et basé sur ses méthodes / paramètres / attributs décide quelle méthode sur l'instance à appeler. Donc, le motif de décorateur ne fonctionnerait pas ici. De toute façon ... le gestionnaire de délégation devrait résoudre le problème
Une délégationHandler pourrait dépendre (par l'intermédiaire d'une injection constructrice) sur d'autres services qui pourraient être (ou doivent être) définis avec un style de vie par demande (ou plus court). Lorsque cela se produit, la délégationHandler devrait avoir une vie aussi courte (ou plus courte) que le style de vie le plus court de ses dépendances.
Une chose drôle est que l'API Web est très similaire à MVC, mais avec MVC icontroller code> S peut être décoré sans problème, car il s'agit du contrôleur
contrôleur code> de la classe de base qui fait toute la réflexion arriver à la bonne action. L'infrastructure appelle simplement l'interface code> icontroller code>. N'est-ce pas bizar que Web API nous fournit avec un
IHTTPCONTROLLER code> abstraction, mais dépend toujours de la mise en œuvre réelle?
Je comprends ton point. J'ai juste essayé de vous montrer comment .. basé sur mon expérience. Les gestionnaires de délégation travaillent assez bien pour toute chose fondamentale en tant que Cors, auth ... pour le reste que nous utilisons l'AOP ... mais comme je l'ai dit ... je voulais juste vous montrer une autre façon de faire ça;)
Et je vous remercie pour votre aide. Merci.
Vous pouvez contourner cela en implémentant Cela se fait facilement en héritant à partir de (j'ai codé dur l'exemple et s'attendre à ce que toute mise en œuvre du monde réel soit plus flexible.) EM > p> ceci a été enregistré dans si vous " D effectivement veux em> faire cela est une autre question - qui connaît les ramifications de modification de ihttpactioninvoker code> et "convertir" le décorateur dans l'instance décorée au point que le
ihttpcontroller code> abstraction n'est plus pertinent.
apicontrolleractioninvoker code>. P>
global.asax.cs code> p>
actionContext code>? p> p>
Dans votre exemple, vous extrayez la décorée du décorateur. Cela ne serait-il pas supprimer le comportement que le décorateur a ajouté? Est-ce que ce comportement sera-t-il encore appelé?
@Steven Oui, je suis sûr que cela contournerait les appels décorés - une solution complète aurait besoin de gérer appelant les méthodes dans la personnalisation ihttpactioninvoker code> et contourner la mise en œuvre par défaut.
Vous pouvez fournir une implémentation personnalisée de Mettre à jour le décorateur pour être générique p> Définir la mise en oeuvre personnalisée de Lorsque vous enregistrez les contrôleurs, ajoutez l'enregistrement d'une version décorée du type de contrôleur p> enregistrer l'implémentation de IHTTPCONTROLLORSELLector CODE> P> ihttpcontrollerselector code> pour modifier le type instancié pour un contrôleur particulier. (Veuillez noter que je n'ai pas testé cela à l'épuisement)
ihttpcontrollerselector code> p>
private MyHttpControllerDecorator<T> DecoratorBuilder<T>(T instance)
where T : IHttpController
{
return new MyHttpControllerDecorator<T>(instance);
}