So what does this have to do with C#? Well C# partially fixed this with the “internal” keyword. Internal members of a class are visible to other classes within the same assembly, but are effectively private as far as classes outside the assembly are concerned. Internal members are very different from protected ones by the way. In the latter case, they are only visible to subclasses (whether in the same assembly or not). However, largely due to a limitation with Visual Studio, internal members used not to be the full answer to the needs of unit testing. The C# compiler supports compiling multiple projects into one assembly, but Visual Studio has a strict one to one project/ assembly mapping. So unit test classes used to have to reside within the same project as the product code (which wasn’t practical if the project’s assembly was a executable, rather than a dll.) The other alternative was to expose all the members that the unit test classes needed to access by making them public.
I talk in the past tense in the previous paragraph as this problem was fixed with the release of C# 2.0. This introduced the idea of Friend Assemblies. To explain, let’s go back to our class A and B. Class A resides in assembly A.dll. Class B resides in assembly B.dll. Normally class B would have no access to the internals of class A. Add the “InternalsVisibleTo” attribute to class A though, specifying B.dll as the trusted assembly and now class B can access those internals. Further, unlike with C++ and friend classes, private members in class A remain private; only internals are exposed via this method.
If both A.dll and B.dll are unsigned, the extra code is just:
which is a pretty neat solution.
Things get really messy though the moment signed assemblies are used. The reason is that one must put the public key (not the nice short token, the full-blown humongous key) in the attribute. So it becomes something like:
(I’ve wrapped the public key across many lines for clarity. In reality, it must be on one line)
The whole horrible nastiness of the matter doesn’t stop there though. To get that public key, one must find the sn.exe tool, plough through its dozens of obscure options, and then run the right one against the required assembly (or run a sequence of two even more obscure commands against the original key file). Then one can cut and paste the output of the command into the attribute in Visual Studio. This is what we in Britain politely term a “complete faff”.
Having banged my head against the wall performing this operation recently, I decided that a simply little utility was required to do all the work. So I wrote an app called FriendAssembly, which I’m sharing here.
FriendAssembly is a basic windows application as shown in the screen-shot below:
The application is simple to use: run it, use the file selector dialog to point at the required signed assembly/ snk file and then hit the copy to clipboard button. Next switch to Visual Studio, put the cursor at the start of the word “class” and hit ctrl-V. All done.
You can download the binary installer here. It is an MSI file that requires the .NET framework version 2. I’ve tested it on WIndows XP and Vista. I’ve no idea if it’ll work with other versions of windows.
Alternatively the source files (as a Visual Studio 2005 solution) are available as a zip file here.
The official documentation on friend assemblies is available here. It’s not very good though in my view.