Yesterday my team mate found in our repository project with linked files. This isn’t something strange here because we’ve struggled with the problem of linked files for a very long time. What IS strange is the fact that those linked files were added to a unit test project.
I dived into this topic and found more of such projects. I also quickly found the true reason of such construction. The picture below shows one of the projects:
As you can see, there is several linked files and only one test class. At this point you probably also suspect what’s going on here – all of those linked classes are of an internal scope and cannot be reached from out of the assembly they are belong to.
As so, it may look appropriate just to add linked file in order to test them. Fortunately .Net framework provides us with tool that allows us to test internal classes in more convenient (and not so barbarian) way 🙂
The tool is called InternalsVisibleToAttribute and may be found in the namespace System.Runtime.CompilerServices. This attribute used on an assembly makes its types visible to the types defined in the specified assembly known also as a „friend assembly”.
What’s noteworthy:
- You can define one on more friend assembly
Attribute is applied at the assembly level, so probably the best place to put it is AssemblyInfo.cs file. To define two friend assemblies, just write two definitions:
[assembly:InternalsVisibleTo(„FriendAssemblyA”)]
[assembly:InternalsVisibleTo(„FriendAssemblyB”)]
[assembly:InternalsVisibleTo(„FriendAssemblyB”)]
or merge them into one:
[assembly:InternalsVisibleTo(„FriendAssemblyA”),
InternalsVisibleTo(„FriendAssemblyB”)]
InternalsVisibleTo(„FriendAssemblyB”)]
- Both the current assembly and the friend assembly must be unsigned or both assemblies must be signed with a strong name
If they’re unsigned, simple:
[assembly: InternalsVisibleTo(„UnitTests”)]
Is enough.
If they’re both strongly signed, then the constructor of the InternalsVisibleToAttribute must consist of the name of the assembly plus the full public key. To do the full procedure:
- Sign UnitTests project with the strong key. Right click on the project, go to „Properties”, then „Signing” tab and check „Sign the assembly” box. Then browse to the key file and that’s it (in simple scenario, for more information on signing go to: https://msdn.microsoft.com/en-us/library/ms247123(v=vs.100).aspx)
- Use strong name tool (sn.exe) to retrieve the full public key from a strong-named key (.snk) file:
- Extract the public key from the strong-named key file to a separate file:
Sn -p snk_file outfile
- Display the full public key to the console (output file isn’t readable): Sn -tp outfile
- Copy and paste the full public key value into your source code
And that’s simply it. In case that some errors related with inaccessibility due to protection level occur, check the code against constructs such as internal methods or similar abominations 🙂