Come dichiarare un'assemblea di amici?


114

Ho 2 progetti nella mia soluzione:

  1. Assembly (libreria di base)
  2. Test Assembly (NUnit)

Avevo dichiarato l'assemblea di prova come assemblea di amici nel primo progetto:

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

Tutto funzionava bene fino a quando mi sono reso conto di aver dimenticato di impostare la soluzione per firmare le mie assemblee. Quindi ha creato un file snk e impostato il progetto di studio visivo per firmare il primo assembly (Libreria di base). Ora quando compilo il primo progetto, ottengo il seguente errore:

Il riferimento all'assembly di amici "Company.Product.Tests" non è valido. Gli assembly firmati con nome sicuro devono specificare una chiave pubblica nelle dichiarazioni InternalsVisibleTo.

Ho provato a estrarre la chiave pubblica dal mio file snk utilizzando l'utilità sn ma genera un file binario cablato che non sono sicuro di come utilizzare. Come posso risolvere il problema?

Risposte:


194

È necessario firmare entrambi gli assembly, perché effettivamente entrambi gli assembly fanno riferimento l'uno all'altro.

Devi mettere la chiave pubblica nell'attributo InternalsVisibleTo. Ad esempio, in Protocol Buffers utilizzo:

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

La chiave pubblica viene recuperata eseguendo

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

In alternativa, scaricalo dal file .snk:

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

7
Ed è dannatamente irritante vedere la documentazione MSDN ( msdn.microsoft.com/en-us/library/… ) menzionare una chiave pubblica ridicolmente corta che a me sembra quasi un token di chiave pubblica .
Hemant

3
Puoi estrarre la chiave pubblica direttamente da un file .snk: sn -k MyStrongnameKey.snk // sn -p MyStrongnameKey.snk public.pk // sn -tp public.pk //
Tim Long

1
Stavo usando il 'titolo dell'assembly' specificato in AssemblyInfo.cs. Da allora, il nome corretto da utilizzare è il "nome dell'assembly" dalla finestra di dialogo Proprietà / Applicazione del progetto (che è nuovamente diverso dal nome del progetto in Esplora soluzioni di Visual Studio).
Colonnello Panic

7
Per quanto utili siano state queste risposte e commenti, avevo bisogno di qualche sperimentazione per rendermi conto che la chiave pubblica è quella dell'assembly contenente i test, NON l'assembly che contiene la dichiarazione 'InternalsInvisibleTo'.
Andreas

3
@Andreas: Beh, va di pari passo con l'assembly che stai nominando: stai specificando il nome sicuro dell'assembly di cui fidarti, all'interno dell'assembly che sta facendo il trust.
Jon Skeet

-3

Puoi ottenere publicKey direttamente dall'assembly che ti interessa, senza magia con 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
Questa non è una risposta a questa domanda. Dovrebbe essere un commento sulla risposta a cui si rivolge
Cole Johnson,

-7

Penso che sia necessario inserire il nome sicuro, che sarebbe qualcosa come "Company.Product.Tests, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 17135d9fcba0119f". Presumo che Company.Product.Tests sia il nome dell'assembly e 17135d9fcba0119f sia la chiave pubblica.

Un altro modo per risolvere questo problema sarebbe quello di non utilizzare assembly separati. Di solito metto il codice sorgente e il codice di test nello stesso assembly. Non so se hai qualche preoccupazione speciale di doverli separare.


Non penso che sia necessario specificare il numero di versione e la lingua (vedere msdn.microsoft.com/en-us/library/… ). Non ho davvero provato a mettere il codice di test nell'assembly stesso. Cercherò di vedere come funziona (+1 per la mancia).
Hemant

4
Per InternalsVisibleTo, PublicKeToken non è sufficiente. Hai bisogno dell'intera chiave pubblica :-(
Sean Reilly,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.