If you are familiar with C++, you’ll know about “friend classes” within that language. If you are not familiar with them, they are a neat way of exposing otherwise private methods to trusted classes. Class A has a bunch of private members, that are obviously hidden to other classes, but there is a problem with this model. Class B is a unit test class that tests class A. Because it is doing unit tests, it needs to delve deep inside class A to check what is going on. By making class B a friend of class A, the former is then granted access to the latter’s inner workings.
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.
Continue reading “C# and Friend Assemblies Made Easy”