Wednesday, 11 October 2006

Every once in a while I make members of my types "internal" so that I can access them inside my assembly but other code (other assemblies) using my types would not have access to those members. The same holds true for all kinds of helper classes that are either designed specifically to handle some internal tasks or whose api is to complicated to be exposed as public. Internal visibility is also the default visibility the class has if not specified otherwise such as in:

class MyClass

Which makes the class "internal" - that is C# compiler defaults to internal.

Suppose now that the project you are working on consists of multiple assemblies be it because every assembly holds types representing different layers or because of the deployement requirements that specify that assemblies should be more granular.

One of the reasons for restricing visibility of types has been mentioned earlier. But what to do in the simple scenario where one company needs to create multiple assemblies, hide some types from public and still be able to use its own "hidden" types across assemblies?

In the old days when I was learning C++ I have learned about "friend classes". Basically what that meant was that one class allowed  other - well known - class to access its otherwise private members. Until recently I thought that It was impossible to do such a thing in .NET, but then came the InternalsVisibleToAttribute...

Although not the same as "friend class" from C++, the InternalsVisibleToAttribute which is new to .NET 2.0 allows you to specify which assembly has access to internal members of the defining assembly. MSDN: "Specifies that all nonpublic types in an assembly are visible to another assembly."

MSDN documentations explains how to use the InternalsVisibleToAttribute, which basically means that to make your internal types available to some other assembly you will need to specify which assemblies should have been able to access the internal types using  an assembly level attribute as follows:

[assembly: InternalsVisibleTo("AssemblyName, PublicKey=123124.....")]

Where AssemblyName is the name of the friend assembly and the PublicKey is the whole public key (not the token) that assembly will be using.

kick it on