J'utilise Si je le configure manuellement tout cela va bien, mais avec l'idée étant celle en ajoutant une "convention" personnalisée à sur le côté plus, il fabrique une mise en cache très indolore - vient de décorer l'interface un peu; Mais est une odeur de code? Et / ou suis-je en train de faire dupliquer quelque chose qui est déjà résolu? P> p> structureMap code> en ce moment, généralement avec la configuration automatique de la Convention (
Scan () CODE>), et je cherche à ajouter des décorateurs Caching dans le pipeline.
scan () code> est juste tellement pratique em> quand vous obtenez beaucoup de dépendances ... m Touchant avec Noting Cache Suggestions em> sur l'interface (s), par exemple: p>
StructureMAP CODE> S Scanning (assez facile) Il peut repérer que les méthodes un ou-autres sont décorées pour la mise en cache et injection automatique d'un décorateur de cache généré dans le pipeline de ce type (générant une clé de cache de l'interface / Nom de la méthode et valeurs de paramètre). p>
7 Réponses :
Le seul inconvénient que je vois ici est qu'il n'ya pas de point central où les objets sont mis en cache. Habituellement, il y a une couche spécifique où la mise en cache est terminée. Avec votre technique, ce n'est pas le cas. P>
Je pense aussi qu'il incombe à votre code de décider si quelque chose doit être mis en cache ou non, pas celui d'une classe / d'une interface. P>
Mais pour répondre à votre question, est-ce une odeur de code? Je dirais non, mais cela pourrait être déroutant pour les nouveaux développeurs d'avoir la suspension de ce système une fois qu'elle est utilisée dans de nombreux endroits. P>
Je ne peux pas dire que je comprends tout totalement, mais pour mes 2 cents, cela semble sans doute bien. Mais je me demande simplement s'il est facile de le changer sans recompilation. Et peut-être souhaiteriez-vous modifier cette durée de cache via une entrée de configuration et non une compilation. Je stockais probablement ces données quelque part où je peux configurer plus facilement. (Peut-être que j'ai mal compris cependant ...) p>
La chose qu'il y a; Toutes les modifications i> (code / config /, etc.) passent par le même processus (serveur de construction, validation, etc.); Il est tout aussi simple d'appuyer sur un code de code via le système, car il s'agit d'une modification d'un fichier de configuration. Sauf dans le code, j'ai une vérification de type statique ;-p
@Marc en effet; Mais peut-être que vous voudrez peut-être le changer en courant (c'est-à-dire que la valeur pourrait être stockée dans une DB?). Je suppose que j'aime avoir toutes les "config" dans le même type de surface, alors vous pouvez tout changer de manière triviale. C'est à dire. Si vous voulez changer tous vos 20 et 40 ans ou similaire. Juste la première chose que j'ai pensée de toute façon. Je ne déteste pas l'idée, mais si c'était moi, je pense que je laisserais cela être configurable quelque part (dB, si votre application sous-jacente utilise une).
Les attributs sont corrects si vous êtes au courant de deux facteurs principaux: P>
structure intrinsèquement décentralisée, au lieu d'un endroit où vous avez vos métadonnées saupoudrées sur chaque composant qu'il touche p> li>
Structure constante de compilateur rigide. Si vous décidez soudainement que votre durée de cache doit être 10, pas 20, vous devez recompiler tout votre code. Vous pouvez rouler des attributs à des choses comme config, mais cela fonctionne autour des attributs et, à ce stade, vous devez vraiment reconsidérer si l'utilisation de ceux-ci était la meilleure idée en premier lieu. P> LI> ul>
Tant que vous êtes au courant de ces problèmes et d'accord avec eux, que d'aller de l'avant. P>
+1 Cette réponse soulève quelques points que je n'avais pas pensé. Plus de munitions contre les attributs :)
Re la seconde; Pour que notre environnement reconstruisant l'entité n'est pas différent de la reconstruction du code de niveau supérieur qui enregistre / configure les choses.
Ce n'est peut-être pas, une partie importante est - elles compilent des constantes de temps, toutes les limitations qui y vont.
J'ai tendance à être d'accord avec ce qui a été dit à propos de la mise en cache qui devait être décidé par votre code, mais un autre scénario que je constate que vous voudrez peut-être prendre en considération est le "ce qui doit être mis en cache, tout l'objet?
Vous voudrez peut-être jouer avec l'idée d'avoir des propriétés pour définir quels membres vous ne voulez pas mettre en cache d'un objet. P>
peut-être un attribut p>
Je pense que cela va sortir de la main rapide (plus d'attributs). Dans ce cas, vous ferez mieux de mettre en place des classes spécifiques pour gérer des "méthodes" spécifiques de la mise en cache qui acceptent des objets avec diverses interfaces spécifiant comment ils souhaitent être mis en cache (ou un tel système de ce type).
Je suis totalement d'accord :) Merci pour la perspicacité.
Autant que je comprends la question, vous envisagez principalement d'ajouter les attributs à faciliter l'enregistrement des conteneurs. Vous mettez toujours en œuvre les caches à l'aide du modèle de conception de décorateur, qui est, IMO, la bonne façon de mettre en œuvre la mise en cache. P>
Nous faisons la même chose dans Safewhere, mais nous utilisons plutôt Strong> basé sur la convention. Nous utilisons également le château Windsor, donc je ne sais pas si cela est possible avec StructureMap, mais nous numérisons simplement les assemblées appropriées après tout ce que tout nommé si l'ajout de l'attribut personnalisé est une odeur de code ou non dépend du degré de réutilisabilité dont vous avez besoin de votre code. Ma règle de base est que je veux être capable em> pour tout câbler avec DI Strong> Pauvre Homme. J'utilise toujours un conteneur di conteneur à la place, mais cette règle me fournit une vérification de la santé mentale. P>
En général, je n'aime pas coupler mon code à un conteneur particulier, mais je ne peux pas vraiment comprendre si vous le faites ici. Cela dépend si vous devez ou non vous devez faire référence à Structuremap pour définir l'attribut personnalisé. Si vous devez référencer la carte de la structure, je considérerais cela une odeur. P> mise en cache * référentiel code> et enregistrez-les comme des décorateurs pour les répertorités réels. Nous avons également un test de l'unité basé sur la Convention qui vérifie que tous les référentiels de mise en cache requis sont présents. P>
Non, l'attribut n'est pas spécifique à un conteneur.
Je pense que quelque chose à considérer chaque fois que vous utilisez des attributs est le couplage de l'intention avec la classe. Le point d'étant que vous ne pouvez pas utiliser cette entité dans une fois placer avec une durée de cache de 10 secondes et une autre place avec une durée de cache de 60 secondes. IMHO C'est toujours le compromis avec des attributs de tout type. P>
Je suis un peu en retard à la fête de celui-ci, mais j'ai réfléchi à ce problème récemment et en général, Utiliser des attributs pour la mise en cache est une odeur de code fort>. P>.
Voici quelques raisons pour lesquelles: P>
la mise en cache de l'attribut peut vous mettre dans un scénario "Way-wagge-wagge", car il peut potentiellement modifier la conception de votre code lorsque vous appliquez des méthodes qui se prêtent à être utilisées par L'attribut de mise en cache, en particulier lorsque vous entrez dans des scénarios complexes. p> li>
La mise en cache par attribut est dangereuse car, tandis que le processus d'ajout d'éléments au cache est généralement le même (c.-à-d. Cache.add (clé, valeur)), processus de détermination de la clé et de l'élément à insérer n'est pas toujours la même et nécessite généralement une sorte de logique qui n'est pas toujours générique. Par exemple, on pense souvent à générer la clé de cache en utilisant les valeurs de paramètre, mais envisagez le scénario dans lequel un paramètre DateTime est utilisé et que l'appelant passe dans DateTime.now ... la valeur de retour pourrait toujours être la même, mais La clé générée par les paramètres sera différente et générera un nouvel objet de cache pour chaque appel. Vous pouvez ensuite modifier la conception de la méthode, mais vous obtenez ensuite exactement le problème décrit dans 1 p> li>
En règle générale, la mise en cache est utilisée pour optimiser un scénario spécifique et il est rare que la raison une raison em> est entrée dans le cache est la même. Supposons que vous ayez un catalogue d'éléments qui changent rarement, vous pouvez décider de charger tout le catalogue dans le cache lorsque l'application commence et mettez-la en cache pendant 12 heures, mais vous pouvez décider de mettre en cache les détails de l'utilisateur d'un utilisateur uniquement après leur connexion. la première fois. La logique requise pour récupérer ces éléments puis les ajouter à un cache est complètement différente et ne se prête pas à être capturée dans un attribut. P> li>
Si vous aviez un attribut de cache, vous auriez également besoin d'un moyen d'expirer les éléments de cache lorsqu'ils changent. En supposant que vous ayez un attribut de cache, vous auriez probablement un attribut «CACHEExpiry» qui aurait les mêmes problèmes ci-dessus, mais vous devez également proposer une manière courante de générer des clés de cache entre méthodes parce qu'elle Soyez hautement improbable que vos paramètres de mise à jour ou de suppression d'un objet soient les mêmes que ceux pour ajouter un objet au cache. p> li>
ol>
La ligne de fond est que sur la cache de surface par attribut semble être une bonne idée, mais dans la pratique de la nature des problèmes que la mise en cache résout signifie qu'il ne se prête pas bien à être piloté par des attributs. P>