Patrick Desjardins Blog
Patrick Desjardins picture from a conference

C# Allow External Library To Access Internal Visibility

Posted on: 2014-12-19

I am not a fan of what I will show you here but it can be a life safer someday in your career. What I will show you is how to access an internal type from an external library. You have read it correctly. Even if the goal of internal visibility is to hide the type to be used outside the assembly, it is possible since framework 2.0 to create an exception by naming which assembly/library that can use the internal type.

Why would we want that? Well, a simple case could be that you want to unit test some internal classes and that you are doing all your unit test in a unit test project. This one needs to access the internal type and you must use a special attribute to allow that. Another case would be that you have the getter public but the setter internal. If you want a specify assembly to be able to write and no other one than you can use this attribute. This force you to have only one way to set information into your property.

The attribute is set anywhere in the code of your assembly. It can be at the top of a class or in AssemblyInfo file. Even if it is at the top of a class, remember that it allows to access the complete assembly. This is why it is a better approach to set the attribute in the AssemblyInfo file.

 [assembly:InternalsVisibleTo("MyBusinessAssembly")] 
 [assembly:InternalsVisibleTo("MyOtherBusinessRelatedAssembly")] 
 [assembly:InternalsVisibleTo("MyUnitTestProjectName")] 

If you are using signed DLL, than you will need to use the sn.exe command line tool. This one can be used directly in the Visual Studio Command Prompt. It will produce a public token that can be used in the InternalsVisibleTo attribute.

 sn -Tp c:\\yourpath\\toyourdll\\abc.dll 
 [assembly:InternalsVisibleTo("MyBusinessAssembly, PublicKey=00000000000111111111111122222222222.....")] 
 [assembly:InternalsVisibleTo("MyOtherBusinessRelatedAssembly, PublicKey=00000000000111111111111122222222222.....")] 
 [assembly:InternalsVisibleTo("MyUnitTestProjectName, PublicKey=00000000000111111111111122222222222.....")]