Wie erkläre ich eine Freundesversammlung?

114

Ich habe 2 Projekte in meiner Lösung:

  1. Assembly (Basisbibliothek)
  2. Testbaugruppe (NUnit)

Ich hatte die Testversammlung im ersten Projekt als Versammlung der Freunde deklariert:

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

Alles funktionierte einwandfrei, bis mir klar wurde, dass ich vergessen habe, die Lösung zum Signieren meiner Baugruppen einzurichten. Erstellen Sie also eine snk-Datei und richten Sie das Visual Studio-Projekt so ein, dass die erste Assembly (Basisbibliothek) signiert wird. Wenn ich jetzt das erste Projekt kompiliere, wird folgende Fehlermeldung angezeigt:

Die Freundschafts-Assembly-Referenz 'Company.Product.Tests' ist ungültig. Assemblys mit starkem Namen müssen in ihren InternalsVisibleTo-Deklarationen einen öffentlichen Schlüssel angeben.

Ich habe versucht, den öffentlichen Schlüssel mit dem Dienstprogramm sn aus meiner snk-Datei zu extrahieren, aber es wird eine drahtgebundene Binärdatei generiert, deren Verwendung ich nicht sicher bin. Wie kann ich das Problem beheben?

Hemant
quelle

Antworten:

194

Sie müssen beide Assemblys signieren , da beide Assemblys effektiv aufeinander verweisen.

Sie müssen den öffentlichen Schlüssel in das Attribut InternalsVisibleTo einfügen. Zum Beispiel verwende ich in Protokollpuffern:

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

Der öffentliche Schlüssel wird durch Ausführen abgerufen

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

Alternativ können Sie es aus der .snk-Datei herunterladen:

sn -p MyStrongnameKey.snk public.pk
sn -tp public.pk
Jon Skeet
quelle
7
Und es ist verdammt irritierend zu sehen, dass in der MSDN-Dokumentation ( msdn.microsoft.com/en-us/library/… ) lächerlich kurze öffentliche Schlüssel erwähnt werden, die für mich fast wie ein Token für öffentliche Schlüssel aussehen .
Hemant
3
Sie können den öffentlichen Schlüssel direkt aus einer .snk-Datei extrahieren: sn -k MyStrongnameKey.snk // sn -p MyStrongnameKey.snk public.pk // sn -tp public.pk //
Tim Long
1
Ich habe den in angegebenen Assembly-Titel verwendet AssemblyInfo.cs. Seitdem ist der richtige Name der zu verwendende Name der Assembly-Name aus dem Dialogfeld Eigenschaften / Anwendung des Projekts (der sich wiederum vom Projektnamen im Solution Explorer von Visual Studio unterscheidet).
Colonel Panic
7
So hilfreich diese Antworten und Kommentare auch waren, ich musste experimentieren, um festzustellen, dass der öffentliche Schlüssel derjenige aus der Assembly ist, der die Tests enthält, NICHT die Assembly, die die Deklaration 'InternalsInvisibleTo' enthält.
Andreas
3
@Andreas: Nun, es passt zu der Assembly, die Sie benennen - Sie geben den starken Namen der Assembly an, der Sie vertrauen möchten, innerhalb der Assembly, die das Vertrauen ausübt.
Jon Skeet
-3

Mit sn.exe können Sie publicKey direkt von einer Assembly abrufen, die Sie interessiert, ohne Magie

<!-- 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))));
Ezyuzin
quelle
1
Dies ist keine Antwort auf diese Frage. Es sollte ein Kommentar zu der Antwort sein, die es anspricht
Cole Johnson
-7

Ich denke, Sie müssen den starken Namen eingeben, der so etwas wie "Company.Product.Tests, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 17135d9fcba0119f" wäre. Ich gehe davon aus, dass Company.Product.Tests Ihr Assemblyname und 17135d9fcba0119f der öffentliche Schlüssel ist.

Eine andere Möglichkeit, dieses Problem zu beheben, besteht darin, keine separaten Assemblys zu verwenden. Normalerweise füge ich den Quellcode und den Testcode in dieselbe Assembly ein. Ich weiß nicht, ob Sie besondere Bedenken haben, dass Sie sie trennen müssen.

user95319
quelle
Ich glaube nicht, dass wir die Versionsnummer und die Kultur angeben müssen (siehe msdn.microsoft.com/en-us/library/… ). Ich habe nicht wirklich versucht, den Testcode in die Assembly selbst einzufügen. Ich werde versuchen zu sehen, wie es funktioniert (+1 für den Tipp).
Hemant
4
Für InternalsVisibleTo reicht PublicKeToken nicht aus. Sie benötigen den gesamten öffentlichen Schlüssel :-(
Sean Reilly