Dépendance persistante de l'assembly en C# .NET
-
08-06-2019 - |
Question
Mon projet C# - nous l'appellerons SuperUI - utilisait une classe d'un assembly externe.Maintenant, ce n'est plus le cas, mais le compilateur ne me laisse pas construire le projet sans la référence d'assembly en place.Permettez-moi de développer.
Ce projet lançait et interceptait une classe d'exception personnalisée - la SuperException
- qui était dérivé du standard System.Exception et vivait dans un assembly séparé et précompilé, SuperAssembly.DLL
, auquel j'ai fait référence.
Finalement, j'ai décidé que c'était un exercice inutile et j'ai remplacé tous les SuperExceptions
avec une System.SuitableStandardException dans chaque cas.J'ai supprimé la référence à SuperException.DLL
, mais je rencontre maintenant ce qui suit en essayant de compiler le projet :
Le type 'SuperException' est défini dans un assembly qui n'est pas référencé.Vous devez ajouter une référence à l'assembly 'SuperException, Version=1.1.0.0 (...)'
Le fichier source référencé par l'erreur ne semble pas pertinent ;c'est l'espace de noms du projet qui est mis en évidence dans l'EDI.
Maintenant, voici le problème :
- Toutes les utilisations de
SuperException
ont été éliminés du code du projet. - Par rapport à un autre projet qui compile correctement sans référence à
SuperException.DLL
, je ne fais référence qu'à un assemblage supplémentaire - etthat
ne fait référence à rien auquel mon projet ne se référence pas.Bien qu'il soit possible que l'une de ces dépendancesSuperExceptions
, je n'attrape que la classe de base Exception et de toute façon...l'autre projet se construit bien ! - J'ai réalisé la "Solution propre" de Visual Studio et j'ai tout effacé à la main à plusieurs reprises.
Ce n'est pas la fin du monde d'inclure cette référence, je ne vois tout simplement pas pourquoi c'est plus nécessaire.Nrrgg.Tous les indicateurs sont les bienvenus !
La solution
Il s'agit probablement d'une référence transitive, où un appel de méthode de type renvoie une instance de SuperException encadrée ("downcast") comme par exemple.Exception, mais de l'inspection du code dans le code inclus de manière transitive, c'est-à-direcode à partir de vos appels de méthode externe, le compilateur sait que vous devez pouvoir obtenir des informations sur ce type à un moment donné.
Resharper vous indiquera où vous devez ajouter une référence, et vous pouvez utiliser le réflecteur de Lütz Roeder, alias RedGate, pour analyser l'IL compilé à la recherche d'une référence à ce type de deux manières :1) utilisez la fonction de recherche, 2) ouvrez chaque type public que vous utilisez et pour celui qui nécessite l'assembly "fantôme", il vous demandera de spécifier son emplacement.
Cela m'arrive le plus souvent lorsque je fais référence à Castle.Windsor mais pas à Castle.MicroKernel.:p
Autres conseils
- Quitter Visual Studio
- Supprimez les dossiers bin et obj dans votre répertoire de solution
- Redémarrez et voyez ce qui se passe
Je suis d'accord avec les autres commentaires ici.Il y a une référence, en texte brut quelque part !J'ai eu des problèmes similaires dans le passé où la recherche dans les fichiers du projet ne renvoyait rien, il s'avère que c'était dans un autre fichier qui n'était pas automatiquement récupéré lors de la recherche.
Je ne pense pas que créer un nouveau projet soit la solution ici.Vous devez être sûr que AUCUN des références dans votre arborescence de dépendances utilisent SuperException. AUCUN
Je n’ai jamais vécu cela au point d’avoir besoin d’effacer littéralement le projet, j’ai toujours trouvé la référence quelque part.Assurez-vous de rechercher chaque déposer.
MODIFIER:
Juste un point à ajouter, si l'emplacement pointé par l'erreur semble aléatoire, cela peut souvent signifier qu'il y a une incompatibilité entre la source compilée et le fichier de code source.Est-ce une application ASP.NET ?Je l'ai déjà eu où les DLL compilées n'ont pas été remplacées lors d'une reconstruction dans le dossier temporaire ASP.NET, ce qui a entraîné des problèmes.Intéressant lors du débogage :)
Je ne pense pas que ce soit un problème de code.Ce que je peux voir, c'est que l'une de vos références existantes s'appuie probablement sur ce type dans ses propres types que vous créez probablement dans votre application.
Si tel est le cas, vous avez besoin de cette référence même si vous n'utilisez pas explicitement le type et même si l'autre assembly référencé a sa propre référence.Vous rencontrez parfois ce problème avec des composants tiers qui nécessitent des références à des types que vous n'avez pas référencés.Le compilateur voit évidemment quelque chose dans l’un de vos assemblys référencés existants et s’attend à ce que vous référenciez celui qui en dépend.
Puisqu'il s'agit d'une erreur du compilateur, il doit y avoir une référence ou une utilisation de SuperException quelque part dans le projet.
- Effectuez une recherche/remplacement dans l'ensemble du projet ou de la solution pour ce type et supprimez chaque référence (il est possible que vous l'ayez déjà fait).
- Si vous faites référence à des types qui héritent de SuperException (même si le type est défini dans un autre assembly), vous avez besoin d'une référence à l'assembly dans lequel SuperException est définie.
Prenez la ligne sur laquelle le compilateur affiche l'erreur et commencez à tracer l'arborescence d'héritage des objets utilisés sur cette ligne, vous pourriez en trouver la source de cette façon.
Merci pour vos réponses jusqu'à présent.J'ai essayé toutes les suggestions (sauf une) en vain.
La suggestion que je n'ai pas essayée est de créer un nouveau projet et d'y ajouter toutes mes affaires, ce qui met vraiment à l'épreuve ma volonté de vivre.;) Je pourrais essayer ça demain si cela me dérange.Merci encore.
Il n'y a vraiment rien de très mystérieux dans les projets VS de nos jours - ce sont tous des fichiers texte, etc.QUELQUE CHOSE doit faire référence à cette classe/dll, et ce quelque chose doit faire partie de votre projet.
Avez-vous vraiment saisi ou trouvé l'ensemble de l'arbre de solutions, chaque fichier, pour une référence à cette exception ?
Cela semble assez étrange.Voici ce que je vérifierais ensuite :
- Vérifiez qu'il n'y a rien qui persiste dans votre fichier Properties/AssemblyInfo.cs.
- Vérifiez qu'il n'y a rien qui persiste dans votre fichier SuperUI.csproj.
- Supprimez toutes les références et ajoutez-les à nouveau.
Essayez de créer un nouveau projet et d'y ajouter toutes vos classes.
récupérez votre dossier de projet.Il peut s'agir d'une référence cachée dans votre projet ou d'un projet auquel votre projet fait référence.Nettoyer avec le Bloc-notes si nécessaire.
Si vous faites référence à des types qui héritent de SuperException (même si le type est défini dans un autre assembly), vous avez besoin d'une référence à l'assembly dans lequel SuperException est définie.
Appuyé sur ce point.
Vous ne faites peut-être pas référence SuperException
, mais vous faites peut-être référence SpecializedSuperException
, qui est dérivé de, ou utilise d'une manière ou d'une autre SuperException
- votre compréhension du projet pour SuperException
mais je ne l'attraperai pas.
Essayez de bidouiller avec l'essai de NDépend
C'est là que des outils comme Affûteur vraiment payant - une simple recherche d'usages me signale généralement plusieurs fois de telles "dépendances fantômes".
Vous pourriez peut-être accéder à votre définition de la classe SuperException et essayer de trouver toutes les références ().Vous souhaiterez peut-être également vérifier si l'assembly SuperException possède un dépendance circulaire sur votre assembly principal (par exemple, l'assembly principal dépend de l'assembly d'exception dépend de l'assembly principal...).
J'ai eu un problème de référence d'assembly très similaire qui se produisait lorsque ma bibliothèque C# avait un assembly C++/CLI dépendant.Le problème était que j'héritais d'une classe publique de cet assembly C++/CLI dans ma bibliothèque d'assemblys C#.Cela signifiait que la chaîne d’héritage s’étendait sur plusieurs assemblys.
J'espérais que n'importe quel client serait assez intelligent pour charger indirectement l'assembly C++/CLI à chaque fois que la bibliothèque C# en avait besoin, mais ce n'était pas le cas même au moment de la compilation.
Je me suis débarrassé de ce problème en rompant l'héritage entre les classes qui s'étendaient sur ces deux bibliothèques d'assemblage et en utilisant l'agrégation à la place.Mon client était enfin satisfait et n'avait plus besoin de l'assembly C++/CLI comme dépendance.
Selon votre mot, vous devrez probablement vous assurer que SuitableStandardException
n'hérite pas de SuperException
afin d'éliminer le SuperException.DLL
pour référence.
Utilisez l'encapsulation au lieu de l'héritage et créez un SuperException
membre de données dans votre nouveau SuitableStandardException
.
Si cela ne résout pas le problème, vous pourriez avoir plus de classes couvrant l'héritage dans certains assemblys, dans votre cas SuperAssembly.DLL
et superException.dll
.
Si vous ne les trouvez pas tous, essayez cette astuce :
Faites en sorte que tous vos membres publics et vos classes soient
SuperAssembly.DLL
interne.Dans SuperAssembly.DLL, faites-vous des amis avec
SuperException.DLL
:[assembly:InternalsVisibleTo("SuperException, PublicKey=0024000004800000....)]
Assurez-vous qu'ils créent et suppriment le
SuperAssembly.DLL
référence de tout client qui fait déjà référenceSuperException.DLL
.
grep -R SuperException *
dans la base de votre projet (obtenez grep
de quelque part en premier) juste pour être sûr.