Làm thế nào để khai báo một hội bạn bè?


114

Tôi có 2 dự án trong giải pháp của mình:

  1. Assembly (Thư viện cơ bản)
  2. Kiểm tra Assembly (NUnit)

Tôi đã khai báo hội thử nghiệm là hội bạn bè trong dự án đầu tiên:

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

Mọi thứ đều hoạt động tốt cho đến khi tôi nhận ra rằng tôi đã quên thiết lập giải pháp để ký hợp đồng của mình. Vì vậy, đã tạo một tệp snk và thiết lập dự án studio trực quan để ký hợp ngữ đầu tiên (Thư viện cơ bản). Bây giờ khi tôi biên dịch dự án đầu tiên, tôi gặp lỗi sau:

Tham chiếu hội bạn bè 'Company.Product.Tests' không hợp lệ. Các tập hợp được ký tên mạnh phải chỉ định một khóa công khai trong khai báo InternalsVibleTo của chúng.

Tôi đã cố gắng giải nén khóa công khai từ tệp snk của mình bằng tiện ích sn nhưng nó tạo ra một tệp nhị phân có dây mà tôi không chắc chắn về cách sử dụng. Làm cách nào để khắc phục sự cố?

Câu trả lời:


194

Bạn cần phải ký vào cả hai tập hợp, vì hiệu quả cả hai tập hợp đều tham chiếu lẫn nhau.

Bạn phải đặt khóa công khai trong thuộc tính InternalsVibleTo. Ví dụ, trong Bộ đệm giao thức tôi sử dụng:

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

Khóa công khai được truy xuất bằng cách chạy

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

Ngoài ra, lấy nó từ tệp .snk:

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

7
Và thật khó chịu khi thấy tài liệu MSDN ( msdn.microsoft.com/en-us/library/… ) đề cập đến khóa công khai ngắn đến mức nực cười, gần giống như mã thông báo khóa công khai đối với tôi.
Hemant

3
Bạn có thể trích xuất các khóa công khai trực tiếp từ một tập tin .snk: sn -k MyStrongnameKey.snk // sn -p MyStrongnameKey.snk public.pk // sn -tp public.pk //
Tim Dài

1
Tôi đã sử dụng 'tiêu đề lắp ráp' được chỉ định trong AssemblyInfo.cs. Từ đó suy ra tên phù hợp để sử dụng là 'tên lắp ráp' từ hộp thoại Thuộc tính / Ứng dụng của dự án (lại khác với tên của dự án trong trình khám phá giải pháp của Visual Studio).
Colonel Panic

7
Vì những câu trả lời và nhận xét này hữu ích, tôi cần một số thử nghiệm để nhận ra rằng khóa công khai là khóa từ assembly chứa các bài kiểm tra, KHÔNG phải là assembly chứa khai báo 'InternalsInvisibleTo'.
Andreas

3
@Andreas: Nó đi cùng với assembly mà bạn đang đặt tên - bạn đang chỉ định tên mạnh của assembly để tin tưởng, trong assembly đang thực hiện việc tin cậy.
Jon Skeet

-3

Bạn có thể trực tiếp lấy publicKey từ assembly mà bạn quan tâm, không cần phép thuật với 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))));

1
Đây không phải là một câu trả lời cho câu hỏi này . Nó phải là một bình luận về câu trả lời mà nó đang giải quyết
Cole Johnson

-7

Tôi nghĩ bạn cần đặt một cái tên mạnh mẽ, sẽ là một cái tên như "Company.Product.Tests, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 17135d9fcba0119f". Tôi giả sử Company.Product.Tests là tên lắp ráp của bạn và 17135d9fcba0119f là khóa công khai.

Một cách khác để giải quyết vấn đề này là không sử dụng các cụm riêng biệt. Tôi thường đặt mã nguồn và mã kiểm tra trong cùng một assembly. Tôi không biết nếu bạn có bất kỳ mối quan tâm đặc biệt mà bạn phải tách chúng ra.


Tôi không nghĩ rằng chúng ta cần chỉ định số phiên bản và văn hóa (xem msdn.microsoft.com/en-us/library/… ). Tôi thực sự không thử đặt mã thử nghiệm trong chính lắp ráp. Sẽ thử và xem nó hoạt động như thế nào (+1 cho mẹo).
Hemant

4
Đối với InternalsVibleTo, PublicKeToken là không đủ. Bạn cần toàn bộ khóa công khai :-(
Sean Reilly, 14/07/09
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.