84 votes

L'attribut InternalsVisibleTo ne fonctionne pas

J'essaie d'utiliser le InternalsVisibleTo pour rendre mes classes internes dans une bibliothèque de classes .NET visibles pour mon projet de test unitaire. Pour une raison quelconque, je continue à obtenir un message d'erreur qui dit :

MyClassName' est inaccessible en raison de son niveau de protection.

Les deux assemblages sont signés et j'ai la bonne clé dans la déclaration d'attribut. Avez-vous une idée ?

1 votes

Pouvez-vous afficher ce que vous avez pour l'attribut InternalsVisibleTo sur la classe que vous essayez d'exposer ? Il est difficile de dire ce qui ne va pas sans voir ce que vous regardez.

109voto

Joe Points 60749

Êtes-vous absolument sûr d'avoir la bonne clé publique spécifiée dans l'attribut ? Notez que vous devez spécifier la clé publique complète, et pas seulement le jeton de clé publique. Cela ressemble à quelque chose comme :

[assembly: InternalsVisibleTo("MyFriendAssembly,
PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73
F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66
A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519
674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C140
6E2F553073FF557D2DB6C5")]

Il y a environ 320 chiffres hexadécimaux. Je ne sais pas pourquoi vous devez spécifier la clé publique complète - peut-être qu'avec seulement la clé publique utilisée dans les références d'autres assemblages, il serait plus facile pour quelqu'un d'usurper l'identité de l'assemblage ami.

54 votes

Pour obtenir la clé publique de l'assemblage d'amis "sn -Tp MyFriendAssembly"

0 votes

@Tyler : C'est pourquoi vous devriez @ les gens. J'ajoute une réponse ci-dessous qui contient une macro VS qui peut être utilisée pour générer l'IVT pour un projet dans votre solution.

12 votes

Pour clarifier le commentaire de @Ian G, ouvrez l'invite de commande de Visual Studio, changez de répertoire (CD) pour atteindre le répertoire contenant le fichier dll de l'assemblage 'friend'. Dans l'invite de commande, tapez sn.exe -Tp NameOfAssembly ou simplement sn - Tp NameOfAssembly comme l'a dit Ian. Il utilise l'outil de nom fort de Microsoft pour trouver et afficher la clé publique complète de l'assemblage. Si vous n'avez qu'un fichier .pub contenant votre clé, vous pouvez l'extraire en utilisant la méthode suivante sn.exe -p NameOfKeyFile.snk NameOfKeyPairFile.pub . Cela créera le fichier clé NameOfKeyFile.snk qui vous permettra ensuite de suivre les instructions précédentes.

45voto

John Beyer Points 158

Un autre "gotcha" possible : Le nom de l'assemblage ami que vous spécifiez dans le champ InternalsVisibleToAttribute doit exactement correspond au nom de l'assemblage de votre ami tel qu'il apparaît dans les propriétés du projet de l'ami (dans l'onglet Application).

Dans mon cas, j'avais un projet Thingamajig et un projet complémentaire ThingamajigAutoTests (les noms ont été changés pour protéger les coupables) qui ont tous deux produit des assemblages non signés. J'ai dûment ajouté l'attribut [assembly: InternalsVisibleTo( "ThingamajigAutoTests" )] au Thingamajig \AssemblyInfo.cs et commenté le fichier AssemblyKeyFile y AssemblyKeyName comme indiqué ci-dessus. Le site Thingamajig s'est bien construit, mais ses membres internes ont obstinément refusé d'apparaître dans le projet autotest.

Après m'être beaucoup creusé la tête, j'ai revérifié les données de la ThingamajigAutoTests et j'ai découvert que le nom de l'assemblage était spécifié comme étant "ThingamajigAutoTests.dll". Bingo - J'ai ajouté l'extension ".dll" au nom de l'assemblage dans le fichier de propriétés du projet. InternalsVisibleTo attribut, et les pièces se sont mises en place.

Parfois, ce sont les plus petites choses...

2 votes

+1 car votre commentaire m'a aidé : dans mon cas, j'avais renommé l'assemblage à un moment donné, mais VS avait laissé le nom de l'assemblage et l'espace de nom par défaut dans les propriétés du projet comme les anciennes valeurs.

3 votes

Hmm. C'est tout le contraire pour moi. J'ai dû supprimer le ".dll" pour la solution à construire.

0 votes

Je peux confirmer que @kmote a raison : j'ai dû supprimer le ".dll" pour que la solution se construise (et qu'Intellisense fonctionne). (.NET 4.5, VS2013, assemblages non signés) Comportement très étrange. Cette question et tous ses réponses sont formidables pour résoudre les problèmes liés à cet attribut apparemment problématique.

38voto

Skimedic Points 471

Si vos assemblages ne sont pas signés, mais que vous obtenez toujours la même erreur, vérifiez que votre fichier AssemblyInfo.cs contient l'une des lignes suivantes :

[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

L'onglet Propriétés affichera toujours votre assemblage comme non signé si l'une de ces lignes (ou les deux) est présente, mais l'attribut InternalsVisibleTo traite un assemblage avec ces lignes comme fortement signé. Supprimez simplement (ou commentez) ces lignes, et cela devrait fonctionner correctement pour vous.

1 votes

Merci, c'était mon problème, et je n'ai trouvé cette réponse nulle part ailleurs.

2 votes

Cela m'a sauvé après avoir obtenu "MyAssembly.dll ne représente pas une assemblée fortement nommée" en appelant sn.exe -Tp MyAssembly.dll

12voto

Colin Desmond Points 2946

Il est intéressant de noter que si l'assemblage "ami" (tests) est écrit en C++/CLI plutôt qu'en C#/VB.NET, vous devez utiliser ce qui suit :

#using "AssemblyUnderTest.dll" as_friend

au lieu d'une référence de projet ou de l'habituel #using déclaration. Pour une raison quelconque, il n'y a aucun moyen de le faire dans l'interface utilisateur de référence du projet.

9voto

Vadim Points 9146

Vous pouvez utiliser Outil AssemblyHelper qui générera la syntaxe InternalsVisibleTo pour vous. Voici le lien vers la dernière version . Notez simplement que cela ne fonctionne que pour les assemblages fortement nommés.

0 votes

Bizarre, même en utilisant cette méthode, cela ne fonctionne toujours pas dans mon application de test .NET core 2.2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X