Атрибут InternalsVisibleTo не работает - PullRequest
       117

Атрибут InternalsVisibleTo не работает

69 голосов
/ 20 сентября 2008

Я пытаюсь использовать атрибут сборки InternalsVisibleTo, чтобы сделать мои внутренние классы в библиотеке классов .NET видимыми для моего проекта модульного теста. По какой-то причине я получаю сообщение об ошибке:

MyClassName недоступно из-за уровня защиты

Обе сборки подписаны, и у меня есть правильный ключ, указанный в объявлении атрибута. Есть идеи?

Ответы [ 19 ]

2 голосов
/ 18 октября 2015

Требуется сгенерировать новый полный открытый ключ для сборки, а затем указать атрибут для сборки.

[assembly: InternalsVisibleTo("assemblyname,
PublicKey="Full Public Key")]

Выполните следующие шаги MSDN , чтобы создать новый полный открытый ключ для сборки из Visual Studio.

Добавление элемента «Получить открытый ключ сборки» в меню «Инструменты»

В Visual Studio выберите Внешние инструменты в меню Сервис.

В диалоговом окне «Внешние инструменты» нажмите Добавить и введите «Получить открытый ключ сборки» в поле «Заголовок».

Заполните поле Command, перейдя к sn.exe. Обычно он устанавливается по следующему адресу: C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0a \ Bin \ x64 \ sn.exe .

В поле Аргументы введите следующее (с учетом регистра): -Tp $ (TargetPath) . Установите флажок «Использовать вывод».

Нажмите OK . Новая команда добавлена ​​в меню «Инструменты».

Когда вам нужен токен открытого ключа разрабатываемой сборки, щелкните команду «Получить открытый ключ сборки» в меню «Инструменты», и токен открытого ключа появится в окне «Вывод».

2 голосов
/ 14 октября 2015

Предыдущие ответы с PublicKey сработали: (Visual Studio 2015: ДОЛЖЕН быть в одной строке, в противном случае он жалуется, что ссылка на сборку недействительна или на нее нельзя ссылаться. PublicKeyToken не работал)

[assembly: InternalsVisibleTo("NameSpace.MyFriendAssembly, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F73F4DDC11F0CA6209BC63EFCBBAC3DACB04B612E04FA07F01D919FB5A1579D20283DC12901C8B66A08FB8A9CB6A5E81989007B3AA43CD7442BED6D21F4D33FB590A46420FB75265C889D536A9519674440C3C2FB06C5924360243CACD4B641BE574C31A434CE845323395842FAAF106B234C2C1406E2F553073FF557D2DB6C5")]

Благодаря @ Джо

Чтобы получить открытый ключ сборки друга:

sn -Tp path\to\assembly\MyFriendAssembly.dll

Внутри командной строки Developper (Автозагрузка> Программы> Visual Studio 2015> Инструменты Visual Studio> Командная строка разработчика для VS2015). Благодаря @Ian G.

Хотя последний штрих, который заставил меня работать после вышесказанного, заключался в том, чтобы подписать мой проект библиотеки друга так же, как подписан проект библиотеки для совместного использования. Поскольку это была новая библиотека Test, она еще не была подписана.

1 голос
/ 29 марта 2018

У меня была такая же проблема. Ни одно из решений не сработало.

В конечном итоге обнаружена проблема, связанная с тем, что класс X явно реализует интерфейс Y, который является внутренним.

метод X.InterfaceMethod был недоступен, хотя я понятия не имею, почему.

Решением было приведение (X как YourInterface) .InterfaceMethod в тестовую библиотеку, и тогда все заработало.

1 голос
/ 19 октября 2017

Я пишу это из-за разочарования. Убедитесь, что сборка, доступ к которой вы предоставляете, названа так, как вы ожидаете.

Я переименовал свой проект, но это не приводит к автоматическому обновлению имени сборки. Щелкните правой кнопкой мыши свой проект и выберите Свойства . В разделе Приложение убедитесь, что Имя сборки и Пространство имен по умолчанию соответствуют вашим ожиданиям.

1 голос
/ 25 ноября 2015

Применяется только в том случае, если вы хотите сохранить неподписанные сборки как неподписанные сборки (и не хотите подписывать их по нескольким причинам):

Есть еще один момент: если вы скомпилируете вашу базовую библиотеку из VS.Net в локальный каталог, она может работать как положено.

НО: как только вы компилируете базовую библиотеку на сетевой диск, применяются политики безопасности, и сборка не может быть успешно загружена. Это снова приводит к сбою VS.NET или компилятора при проверке соответствия PublicKey.

НАКОНЕЦ, можно использовать неподписанные сборки: https://msdn.microsoft.com/en-us/library/bb384966.aspx Вы должны убедиться, что ОБА сборки не подписаны А атрибут Assembly должен быть без информации PublicKey:

<Assembly: InternalsVisibleTo("friend_unsigned_B")>

0 голосов
/ 03 декабря 2018

1- Подпишите тестовый проект: В Visual Studio перейдите в окно свойств , тестовый проект и Подпишите сборку , установив флажок с помощью та же фраза на вкладке Подпись .

2 - Создайте PublicKey для тестового проекта: Откройте командную строку Visual Studio (например, Командная строка разработчика для VS 2017). Перейдите в папку, где находится файл .dll , тестовый проект . Создать открытый ключ через sn.exe:

sn -Tp TestProject.dll

Обратите внимание, что аргумент -Tp, но не -tp.

3 - Представьте PublicKey для тестируемого проекта: Перейдите в файл AssemblyInfo.cs в тестируемом проекте и добавьте эту строку с PublicKey, созданным в предыдущий шаг:

* +1026 * [сборка: InternalsVisibleTo ( " TestProjectAssemblyName * +1028 *, ОткрытыйКлюч = 2066212d128683a85f31645c60719617ba512c0bfdba6791612ed56350368f6cc40a17b4942ff16cda9e760684658fa3f357c137a1005b04cb002400000480000094000000060200000024000052534131000400000100010065fe67a14eb30ffcdd99880e9d725f04e5c720dffc561b23e2953c34db8b7c5d4643f476408ad1b1e28d6bde7d64279b0f51bf0e60be2d383a6c497bf27307447506b746bd2075")] Не забудьте заменить вышеуказанный PublicKey на ваш. 4- Сделать внутренний метод внутренним: В тестируемом проекте изменить модификатор доступа метода на внутренний. внутренняя статика void DoSomething () {...}
0 голосов
/ 29 марта 2018

Если у вас имеется более 1 ссылочной сборки - убедитесь, что все необходимые сборки имеют атрибут InternalsVisibleTo. Иногда это не очевидно, и нет сообщения о том, что вам нужно добавить этот атрибут еще в одну сборку.

0 голосов
/ 26 апреля 2012

В качестве примечания: если вы хотите легко получить открытый ключ без использования sn и выяснить его параметры, вы можете загрузить удобную программу здесь . Он не только определяет открытый ключ, но и создает строку «assembly: InternalsVisibleTo ...», готовую для копирования в буфер обмена и вставки в ваш код.

0 голосов
/ 26 февраля 2013

Я только что решил похожую проблему с атрибутом InternalsVisibleTo. Все казалось правильным, и я не мог понять, почему внутренний класс, к которому я стремился, все еще не был доступен.

Смена регистра ключа с верхнего на нижний регистр устранила проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...