How to use InternalsVisibleTo with strong named assemblies

 

Routinely I am forgetting how to do this ­čÖé So to make life easier I am writting up a blog posting. 

When writting unit tests for VS2008/VS2010 you will may find yourself needing to access internals.  While it is possible to use the “_Accessor” classes, this is not always a friendly way to write tests (especially for complex objects and operations)

To that end, there is a nice and easy way (once you jump through a copy of configuration hoops) to handle this and that is via the “InternalsVisibleTo” attribute that lives at the assembly level.

I usually place my in the AssemblyInfo.cs file

 

[assembly: InternalsVisibleTo("MyProject.Tests")]

 

Now the trick comes when your assembly is signed with a Strong Name.  When this is the case, you will most likely receive the following error when you attempt to compile:

 

Error: "Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations"

To fix this, we must do two things.  The first is that you must sign the test assembly, and the second is that you must include the public key in the InternalsVisibleTo statement. 

To get the public key value from the .snk file, use the sn.exe utility included in the .NET SDK. You must do two things, first, create a .snk file that contains only the public key:

 

sn -p MyKey.snk MyKey.PublicKeyOnly.snk

Then, you can extract the public key value with this command:

 

sn -tp MyKey.PublicKeyOnly.snk

This will produce a similar output:

Public key is

0024000004800000940000000602000000240000525341310004000001000100cfb8bc23b86a08e70d021dd53d3b0293e716e71015870bdcc58a0231a4228618851a83e06077f5a44f42beb2baf356ad2d344521a96b0081ed0f25f9227523e3625eda524efe1cf2e1e5e41f3693a76ec52347684b8129a4bb2d5fc49681adf33da0eecc4f81f011af4539d12abe1b4e760b5ce32d766db1012d44028381f0b4

Public key token is 2ff2b71993eeff95

Once you get this, copy the public key value (the really long one) and update the InternalsVisibleTo:

 

[assembly: InternalsVisibleTo("MyProject.Tests,  PublicKey=0024000004800000940000000602000000240000525341310004000001000100cfb8bc23b86a08e70d021dd53d3b0293e716e71015870bdcc58a0231a4228618851a83e06077f5a44f42beb2baf356ad2d344521a96b0081ed0f25f9227523e3625eda524efe1cf2e1e5e41f3693a76ec52347684b8129a4bb2d5fc49681adf33da0eecc4f81f011af4539d12abe1b4e760b5ce32d766db1012d44028381f0b4")]

Voila! You can now access the internals from your test project for strong named assemblies.