You come across several situations where you need to develop a set of class libraries, say a framework of sorts, and there are several classes within certain assemblies which need to be marked as internal. You go ahead and mark them as internal, and then realize that there are other classes, within the framework, which are dependent on these marked classes, but exist in other assemblies. This is a problem, and you have no choice – you mark these classes as public and then document that the particular class should not be used directly from the code. You may think that this is a bad design, in a way, but there are no shortage of these in the .NET BCL. How often do you come across MSDN documentation which reads something like:
“This class supports the .NET Framework infrastructure and is not intended to be used directly from your code.”?
Ideally, these should have been internal classes, but you simply cannot have them that way. StrongNameIdentityPermission provides an alternative, but it isn’t always practical.
In .NET Framework 2.0, there exists a decent workaround to this problem. A new attribute called InternalsVisibleToAttribute has been introduced, which when applied to an assembly indicates that all internal types in that assembly would be visible to another assembly, whose name is specified in the attribute constructor. In other words, that assembly becomes a friend assembly. The usage would be something like:
Or (for a strong-named friend)
Don’t get carried away, refer to this MSDN section to know more about the constraints and other considerations while using this attribute.
Now, what could be the usage scenarios for this attribute? I have already explained one such scenario in the earlier sections of this post. Another case may be that of unit test assemblies. Typically, we keep unit tests in separate assemblies. Now, to be able to test all the internal classes/methods, it would be useful to gain visibility into them. So, we may declare the unit-test assembly as a friend of the actual assembly.
[Digression: Adroit users of VS 2005 may quickly pounce upon the last use. VS 2005 unit testing framework provides reflection-based helpers which help you write tests against non-public members of a class. So, it’s left to you to decide which a better choice is]