Notre logiciel a plusieurs classes qui devraient être trouvées dynamiquement via la réflexion. Les classes ont toutes un constructeur avec une signature spécifique via laquelle le code de réflexion instancie les objets.
Cependant, lorsque quelqu'un vérifie si la méthode est référencée (par exemple via Visual studio Code Lens), la référence via réflexion n'est pas comptée. Les gens peuvent manquer leurs références et supprimer (ou modifier) des méthodes apparemment inutilisées.
Comment marquer / documenter les méthodes destinées à être appelées par réflexion?
Idéalement, la méthode devrait être marquée de telle manière que les collègues et Visual Studio / Roslyn et d'autres outils automatisés «voient» que la méthode est destinée à être appelée via la réflexion.
Je connais deux options que nous pouvons utiliser, mais les deux ne sont pas tout à fait satisfaisantes. Étant donné que Visual Studio ne peut pas trouver les références:
- Utilisez un attribut personnalisé et marquez le constructeur avec cet attribut.
- Un problème est que les propriétés d'attribut ne peuvent pas être une référence de méthode, par conséquent le constructeur affichera toujours comme ayant 0 références.
- Les collègues qui ne connaissent pas l'attribut personnalisé l'ignoreront probablement.
- Un avantage de mon approche actuelle est que la partie réflexion peut utiliser l'attribut pour trouver le constructeur qu'elle doit appeler.
- Utilisez des commentaires pour documenter qu'une méthode / constructeur doit être appelé via la réflexion.
- Les outils automatisés ignorent les commentaires (et les collègues peuvent également le faire).
- Les commentaires de documentation Xml peuvent être utilisés pour que Visual Studio compte une référence supplémentaire à la méthode / constructeur:
SoitMyPlugin
la classe dont le constructeur à invoquer via la réflexion. Supposons que le code de réflexion appelant recherche les constructeurs qui prennent unint
paramètre. La documentation suivante fait que la lentille de code montre le constructeur ayant 1 référence:
/// <see cref="MyPlugin.MyPlugin(int)"/> is invoked via reflection
Quelles meilleures options existent?
Quelle est la meilleure pratique pour marquer une méthode / un constructeur qui doit être appelé via la réflexion?
la source
Réponses:
Une combinaison des solutions suggérées:
Cela devrait clarifier l'utilisation prévue pour les collègues (et mon futur moi-même).
<see>
-tag pour augmenter le nombre de références pour le constructeur / méthode.Cela rend cette lentille de code et les références de recherche montrent que le constructeur / méthode est référencé.
UsedImplicitlyAttribute
[UsedImplicitly]
a précisément la sémantique voulue.PM>
Install-Package JetBrains.Annotations
.SupressMessageAttribute
pour le messageCA1811: Avoid uncalled private code
.Par exemple:
La solution confère l'utilisation prévue du constructeur aux lecteurs humains et aux 3 systèmes d'analyse de code statique les plus utilisés avec C # et Visual Studio.
L'inconvénient est qu'un commentaire et une ou deux annotations peuvent sembler un peu redondants.
la source
MeansImplicitUseAttribute
qui peut être utilisé pour créer vos propres attributs qui ont unUsedImplicitly
effet. Cela peut réduire beaucoup de bruit d'attribut dans les bonnes situations.Je n'ai jamais eu ce problème dans un projet .Net, mais j'ai régulièrement le même problème avec les projets Java. Mon approche habituelle consiste à utiliser l'
@SuppressWarnings("unused")
annotation en ajoutant un commentaire expliquant pourquoi aussi). Cela a l'avantage de garantir automatiquement que les outils d'analyse statique sont conscients que le code n'est pas censé avoir des références directes et de donner une raison détaillée aux lecteurs humains.L'équivalent C # de Java
@SuppressWarnings
estSuppressMessageAttribute
. Pour les méthodes privées , vous pouvez utiliser le message CA1811: Évitez le code privé non appelé ; par exemple:la source
SuppressMessageAttribute
( msdn.microsoft.com/en-us/library/... ). Le message le plus proche estCA1811: Avoid uncalled private code
( msdn.microsoft.com/en-us/library/ms182264.aspx ); Je n'ai pas encore trouvé de message pour le code public.Une alternative à la documentation serait d'avoir des tests unitaires pour s'assurer que les appels de réflexion s'exécutent correctement.
De cette façon, si quelqu'un modifie ou supprime les méthodes, votre processus de génération / test devrait vous alerter que vous avez cassé quelque chose.
la source
Eh bien, sans voir votre code, cela ressemble à ceci serait un bon endroit pour introduire un héritage. Peut-être une méthode virtuelle ou abstraite que le constructeur de ces classes peut appeler? Si vous êtes la méthode que vous essayez de marquer est juste le constructeur, alors vous essayez vraiment de marquer une classe et non une méthode ouais? Quelque chose que j'ai fait dans le passé pour marquer les classes est de créer une interface vide. Ensuite, les outils d'inspection de code et la refactorisation peuvent rechercher des classes qui implémentent l'interface.
la source