친구 어셈블리를 선언하는 방법은 무엇입니까?


114

내 솔루션에 2 개의 프로젝트가 있습니다.

  1. 어셈블리 (기본 라이브러리)
  2. 테스트 어셈블리 (NUnit)

첫 번째 프로젝트에서 테스트 어셈블리를 친구 어셈블리로 선언했습니다.

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

어셈블리에 서명하는 솔루션을 설정하는 것을 잊었다는 것을 깨달을 때까지 모든 것이 잘 작동했습니다. 그래서 snk 파일을 만들고 첫 번째 어셈블리 (기본 라이브러리)에 서명하도록 Visual Studio 프로젝트를 설정했습니다. 이제 첫 번째 프로젝트를 컴파일 할 때 다음 오류가 발생합니다.

Friend 어셈블리 참조 'Company.Product.Tests'가 잘못되었습니다. 강력한 이름으로 서명 된 어셈블리는 InternalsVisibleTo 선언에 공개 키를 지정해야합니다.

sn 유틸리티를 사용하여 snk 파일에서 공개 키를 추출하려고했지만 사용 방법이 확실하지 않은 유선 바이너리 파일이 생성됩니다. 문제를 어떻게 해결할 수 있습니까?

답변:


194

효과적으로 두 어셈블리가 서로를 참조하므로 어셈블리에 모두 서명해야합니다 .

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

7
그리고 MSDN 문서 ( msdn.microsoft.com/en-us/library/… )에서 공개 키 토큰 처럼 보이는 엄청나게 짧은 공개 키를 언급 하는 것은 짜증이납니다 .
Hemant 2009-07-14

3
.snk 파일에서 직접 공개 키를 추출 할 수 있습니다. sn -k MyStrongnameKey.snk // sn -p MyStrongnameKey.snk public.pk // sn -tp public.pk //
Tim Long

1
에 지정된 '어셈블리 제목'을 사용하고있었습니다 AssemblyInfo.cs. 그 이후로 추론 된 올바른 이름은 프로젝트의 속성 / 응용 프로그램 대화 상자에서 '어셈블리 이름'입니다 (Visual Studio 솔루션 탐색기의 프로젝트 이름과 다시 다름).
패닉 대령

7
이러한 답변과 의견이 도움이 되었기 때문에 공개 키가 'InternalsInvisibleTo'선언을 포함하는 어셈블리가 아니라 테스트를 포함하는 어셈블리의 공개 키라는 것을 깨닫기 위해 몇 가지 실험이 필요했습니다.
Andreas

3
@Andreas : 이름을 지정하는 어셈블리와 함께 진행됩니다. 신뢰할 수있는 어셈블리 내에서 신뢰할 수있는 어셈블리의 강력한 이름을 지정합니다.
Jon Skeet

-3

sn.exe를 사용하면 마법없이 관심있는 어셈블리에서 publicKey를 직접 가져올 수 있습니다.

<!-- 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))));

1
이것은 질문에 대한 답이 아닙니다 . 그것은 그것이 다루고있는 대답
Cole Johnson

-7

"Company.Product.Tests, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 17135d9fcba0119f"와 같은 강력한 이름을 입력해야한다고 생각합니다. Company.Product.Tests가 어셈블리 이름이고 17135d9fcba0119f가 공개 키라고 가정합니다.

이 문제를 해결하는 또 다른 방법은 별도의 어셈블리를 사용하지 않는 것입니다. 저는 보통 소스 코드와 테스트 코드를 같은 어셈블리에 넣습니다. 나는 당신이 그들을 분리해야 할 특별한 관심사가 있는지 모르겠습니다.


버전 번호와 문화권을 지정할 필요가 없다고 생각합니다 ( msdn.microsoft.com/en-us/library/… 참조 ). 나는 실제로 어셈블리 자체에 테스트 코드를 넣는 것을 시도하지 않았습니다. 그것이 어떻게 작동하는지 시도하고 볼 것입니다 (팁은 +1).
Hemant

4
InternalsVisibleTo의 경우 PublicKeToken으로는 충분하지 않습니다. 당신은 전체 공개 키 :-( 필요
숀 라일리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.