Know your enemies with Friendly Assemblies
Recently I was asked to make certain members of an assembly accessible to a defined set of friendly assemblies. After a short recherche it was obvious that we need to use InternalsVisibleTo. Since there was no good guide on how to use that mighty attribute, we decided to make a small guide for our readers.
The solution and its friendly assemblies
We start with a Blank Solution and describe everything as detailed as possible.
To create a Blank Solution start your Visual Studio 2012 and wait until it is loaded. When Visual Studio is ready press [CTRL] + [SHIFT] + [n]. The New Project Dialog will open. Adjust your selection according to the next screenshot and give your Solution a name.
Click the OK button to create your Blank Solution. Now we need some Projects in our Solution to demonstrate the behavior we’ll need at least 3 Solutions. One Console Application and two ClassLibraries. We select File – Add – New Project in Visual Studio and create Projects with the following names. Just make your selection according to the following screenshots.
Now we have the project structure for our little demo application.
Setup the Solution to use Strong-Name Signing
Its time to sign our assemblies to be able to identify the friendly assemblies.
Start the “Developer Command Prompt for VS2012” enter your Solution directory and execute the following steps.
In our example we will generate only one KeyPair that will be used to sign all Assemblies.
When everything worked out you will see something similar to the following screenshot.
Now we configure Signing for our Projects, repeat this steps for all Projects in the Solution.
- Click the Project in the Solution Explorer.
- Press [ALT] + [Enter] to open the Properties Window.
- Click on Signing on the left side.
- Check Sign the assembly.
- Select “<Browse…>” in the now enabled Drop Down box.
- Select the generated .snk file in the opened File Open Dialog box.
- Click Open.
- Press [CTRL] + [s] to save the changes.
Press [CTRL] + [b] to start a build and make sure everything is still working.
Put some spread on the bread
Now that the Solution is set up, we add some Code to our projects.
Start with the “at.automism.FriendlyAssemblies.Secret” Project. Visual Studio already generated a class for us, we’re going to change it to fit our needs.
There is nothing spectacular about our Greeter Class. It just defines two Methods and sets the access modifier of one of the methods to internal.
Now we add the “at.automism.FriendlyAssemblies.Consumer” as friendly assembly. Open the AssemblyInfo.cs file located in the Properties folder of the Project “at.automism.FriendlyAssemblies.Secret”.
At the end of the file add the InternalsVisibleToAttribute like in the following example.
The Parameter for the Attribute is defined as “<name of the friendly assembly>, PublicKey=<key found in the at.automism.FriendlyAssemblies.txt file>”. Make sure to remove all line breaks from the public key.
Now we add a reference to our “at.automism.FriendlyAssemblies.Secret” in the other two Projects.
- Right click the References Folder of the Project.
- Select “Add Reference…”.
- On the left side of the opened window select Solution – Projects.
- Check the box right in front of the desired Project.
- Click OK when finished.
When you have added the references hit [CTRL] + [b] and make sure the build works as expected.
Now we modify the code in the “at.automism.FriendlyAssemblies.Public” Project. Just modify the already existing class to look like the snippet below.
You probably have noticed that you can’t access the WhisperHello Method from that file. That happens because the the method is only visible to friendly assemblies.
We add a reference to “at.automism.FriendlyAssemblies.Public” to the “at.automism.FriendlyAssemblies.Consumer” Project. Just follow the steps done earlier.
Adjust the Program.cs file to look like the following snippet.
Have you noticed how WisperHello was available in Intellisense when making the adjustments?
When everything went OK you can hit F5 and will be presented with something similar to the screenshot below.
This post is also available in: German