Атрибут InternalsVisibleTo не работает [.net]


Answers

Если ваши сборки не подписаны, но вы по-прежнему получаете ту же ошибку, проверьте файл AssemblyInfo.cs для любой из следующих строк:

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

Вкладка свойств по-прежнему будет показывать вашу сборку как unsigned, если присутствуют (или оба) этих строк, но атрибут InternalsVisibleTo рассматривает сборку с этими строками как сильно подписанную. Просто удалите (или запишите) эти строки, и это должно сработать для вас.

Question

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

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

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




Стоит отметить, что если сборка «друзей» (тестов) написана на C ++ / CLI, а не на C # / VB.Net, вам необходимо использовать следующее:

#using "AssemblyUnderTest.dll" as_friend

вместо ссылки на проект или обычного оператора #using. По какой-то причине в пользовательском интерфейсе проекта нет никакого способа сделать это.

Colin




Вот макрос, который я использую для быстрого создания этого атрибута. Это немного взломанный, но он работает. На моей машине. Когда последний подписанный двоичный файл находится в /bin/debug . Etc equivocation и т. Д. Во всяком случае, вы можете видеть, как он получает ключ, так что это даст вам подсказку. Исправить / улучшить, как позволяет ваше время.

Sub GetInternalsVisibleToForCurrentProject()
    Dim temp = "[assembly:  global::System.Runtime.CompilerServices." + _
               "InternalsVisibleTo(""{0}, publickey={1}"")]"
    Dim projs As System.Array
    Dim proj As Project
    projs = DTE.ActiveSolutionProjects()
    If projs.Length < 1 Then
        Return
    End If

    proj = CType(projs.GetValue(0), EnvDTE.Project)
    Dim path, dir, filename As String
    path = proj.FullName
    dir = System.IO.Path.GetDirectoryName(path)
    filename = System.IO.Path.GetFileNameWithoutExtension(path)
    filename = System.IO.Path.ChangeExtension(filename, "dll")
    dir += "\bin\debug\"
    filename = System.IO.Path.Combine(dir, filename)
    If Not System.IO.File.Exists(filename) Then
        MsgBox("Cannot load file " + filename)
        Return
    End If
    Dim assy As System.Reflection.Assembly
    assy = System.Reflection.Assembly.Load(filename)
    Dim pk As Byte() = assy.GetName().GetPublicKey()
    Dim hex As String = BitConverter.ToString(pk).Replace("-", "")
    System.Windows.Forms.Clipboard.SetText(String.Format(temp, assy.GetName().Name, hex))
    MsgBox("InternalsVisibleTo attribute copied to the clipboard.")
End Sub



В дополнение ко всему вышесказанному, когда все кажется правильным, но друг узел упорно отказывается видеть любые внутренние, перезарядка решение или перезапуска Visual Studio может решить эту проблему.




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

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

Благодаря @Joe

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

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

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

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




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

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

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

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

<Assembly: InternalsVisibleTo("friend_unsigned_B")>




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

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




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

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