One of the projects I work on wasn’t using strongly-named assemblies, so we decided to sign them (mainly to prevent version conflicts on sales laptops). However, after generating the key-pair and setting up the different assemblies to use it, building the solution gave this error:
Friend assembly reference ‘Company.Product.UnitTests’ is invalid. Strong-name signed assemblies must specify a public key token in their
The problem was that some of the assemblies were making their internals visible to the UnitTests assembly (making them accessible so that they could be tested), but when these assemblies are strongly names, the public key token must also be included in the
InternalsVisibleTo declaration in Assembly.cs.
This introduces a chicken-and-egg scenario; the A assembly makes its internals visible to the UnitTests assembly, but must know the UnitTests assembly public key in order to build. The UnitTests assembly depends on assembly A to build, but assembly A can’t be built until we know what the public key token for UnitTests is, which in turn can’t build because it depends on assembly A…
- Sign all assemblies with the key-pair
- Generate the public key for the key-pair as such (from the Visual Studio command prompt):
sn -p path\to\keypair.snk path\to\keypair.pub
- Get the public key token for the public key as such (still from the Visual Studio command prompt):
sn -tp path\to\keypair.pub
This will output a long (256 characters) public key; copy this to the clipboard
- Declare the
InternalsVisibleToattribute in Assembly.cs as such:
[assembly: InternalsVisibleTo("Company.Product.UnitTests, PublicKey=<your public key>")]
<your public key>is replaced by the public key output in (3)
- Build the solution. The solution should now build as expected.
This assumes that all assemblies use the same key-pair - suggestions to use the public key token (using
PublicKeyToken=... rather than
PublicKey=...) didn’t work for me.