Occasionally you may want to access internal classes and their members found in one assembly from code in a separate assembly. The 'internal' modifier prevents this type of access. This restriction can be circumvented using C# 2.0 friend assemblies.
The Internal Modifier
NOTE: The use of friend assemblies is good for testing purposes. If you use friend assemblies for other purposes, you should consider your design to ensure that you are not breaking the rules of encapsulation.
Creating Friend Assemblies
To demonstrate, create a new, blank solution in Visual Studio named "FriendAssemblyDemo". Add two projects to this solution. The first should be a console application named "Caller" and the second should be a class library named "InternalsVisible". The Caller application will access an internal class in the InternalsVisible assembly. To link the two assemblies, add a reference to the class library within the console application.
We can now add an internal class to the InternalsVisible project. Modify the automatically created class file as follows:
Modify the Program class in the console application as shown below:
static void Main(string args)
InternalsVisible.World world = new InternalsVisible.World();
If you attempt to compile the solution, you will see a compiler error. This error indicates that the InternalsVisible.World class cannot be accessed due to its protection level. To specify that the internals of the InternalsVisible project should be available to the Caller application, we need to add the following attribute to the class library's assembly. This line should appear outside of any namespace or class declaration.
NOTE: This attribute is found in the System.Runtime.CompilerServices namespace so ensure that the code file in which it appears includes the line, using System.Runtime.CompilerServices;
You should now be able to compile and execute the solution.
Working with Signed Assemblies
[assembly: InternalsVisibleTo("Caller, PublicKey=0024000004800000940000000602000000240000
NOTE: The key must appear on a single line.
The public key can be obtained using the strong name tool in a two-stage process. Firstly, the public key must be extracted from the key file into a new file. This is achieved using the "p" switch. For example, if the key file is named "Caller.snk", you can copy the public key to a new file named "public.key" from the Visual Studio command line using the following command:
sn.exe -p Caller.snk public.key
The second stage is to view the contents of the new public key file in hexadecimal format. This can be outputted using the following command. The key value should then be copied and pasted into the assembly attribute.
sn.exe -tp public.key