InternalsVisibleTo and Strong Names

I just stumbled upon a funny problem related to the new .NET 2.0 attribute InternalsVisibleTo in conjunction with a strong-named assembly. The situation is this: I have that assembly that exposes its internals to another assembly (for unit testing) using InternalsVisibleTo.

Now I decided to sign that assembly with a strong name. Suddenly, I got the following error message at compile time: Friend assembly reference ‘UnitTests’ is invalid. Strong-name signed assemblies must specify a public key token in their InternalsVisibleTo declarations. So what to do about this? Well, first the UnitTests assembly needs to be signed with a strong name, too. Then the tricky part is using the correct string to pass to the InternalsVisibleTo attribute. Problem is, you won’t be able to compile either of the two assemblies before you get that syntax right: the UnitTests assembly doesn’t compile because it references the other assembly, which can’t be compiled because the attribute is not correctly configured. The trick is to find out the public key token of the strong name key pair you are using to sign the UnitTests assembly. There are several ways to do that:

  1. Find any other assembly in the GAC that has been signed with the same strong name and copy the public key token from the properties dialog.
  2. From the command line, use the sn.exe tool to show the public key token for an assembly that’s already signed: sn.exe -T assembly.dll (note the capital T)
  3. From the command line, use the sn.exe tool to show the token for a public key that you have saved in a file: sn.exe -t mykey.pub If you have your key pair together in one file, you’ll need to extract the public key into a separate file first: sn.exe -p mykey.snk mykey.pub

There are other ways, especially if you’re using a key pair stored in a container. Use the sn.exe command without parameters to get some helpful information on parameter syntax. In either case, you should end up with your public key token, which is a string representing an eight byte hexadecimal number. The final step to get the assembly combination to compile correctly is to include the public key token in the parameter to the InternalsVisibleTo attribute in the correct syntax (use your own public key token, obviously):

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("UnitTests, PublicKeyToken=123456789abcdef0")]

Sorry, this blog does not support comments.

I used various blog hosting services since this blog was established in 2005, but unfortunately they turned out to be unreliable in the long term and comment threads were lost in unavoidable transitions. At this time I don't want to enable third-party services for comments since it has become obvious in recent years that these providers invariably monetize information about their visitors and users.

Please use the links in the page footer to get in touch with me. I'm available for conversations on Keybase, Matrix, Mastodon or Twitter, as well as via email.