Как объявить сборку друга?

У меня есть 2 проекта в моем решении:

  • Сборка (основная библиотека)
  • Контрольная сборка (NUnit)

Я объявил тестовую сборку как сборку друзей в первом проекте:

[assembly: InternalsVisibleTo ("Company.Product.Tests")]

Все работало нормально, пока я не понял, что забыл настроить решение для подписывания своих собраний. Созданный файл snk и настройка проекта визуальной студии для подписи первой сборки (Basic Library). Теперь, когда я скомпилирую первый проект, я получаю следующую ошибку:

Ссылка на сборку друга 'Company.Product.Tests' недействителен. Скрепленные подписью собрания должны указать открытый ключ в их InternalsVisibleTo объявления.

Я попытался извлечь открытый ключ из моего файла snk с помощью утилиты sn, но он генерирует проводной двоичный файл, который я не уверен, как использовать. Как я могу исправить проблему?

Ответ 1

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

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

[assembly:InternalsVisibleTo("Google.ProtocolBuffers.Test,PublicKey="+
"00240000048000009400000006020000002400005253413100040000010001008179f2dd31a648"+
"2a2359dbe33e53701167a888e7c369a9ae3210b64f93861d8a7d286447e58bc167e3d99483beda"+
"72f738140072bb69990bc4f98a21365de2c105e848974a3d210e938b0a56103c0662901efd6b78"+
"0ee6dbe977923d46a8fda18fb25c65dd73b149a5cd9f3100668b56649932dadd8cf5be52eb1dce"+
"ad5cedbf")]

Открытый ключ извлекается при запуске

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

В качестве альтернативы получить его из файла .snk:

sn -p MyStrongnameKey.snk public.pk
sn -tp public.pk

Ответ 2

Вы можете напрямую получить publicKey с сборки, которая вам интересна, без магии с sn.exe

<!-- language: c# -->
var assemblyName = Assembly.GetExecutingAssembly().GetName();
Console.WriteLine("{0}, PublicKey={1}",
    assemblyName.Name,
string.Join("", assemblyName.GetPublicKey().Select(m => string.Format("{0:x2}", m))));

Ответ 3

Я думаю, вам нужно указать сильное имя, которое было бы чем-то вроде "Company.Product.Tests, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 17135d9fcba0119f". Я предполагаю, что Company.Product.Tests - это имя вашей сборки, а 17135d9fcba0119f - открытый ключ.

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