Safely exposing an assemblies internals using the InternalsVisibleTo attribute.

I have been looking after an application for a while that constructs some of its interface from MSSQL database entries. Recently we were tasked with creating an administration tool to create these database entries (essentially creating an interface builder – but with quite a bit of specific business logic tied in).

One issue we faced while doing this was that the client wanted a ‘preview’ of the interface they were building – basically they wanted to test run the forms they were building and have them perform and behave in the exact same way they would if they were being utilised in the main application.

Now the main application is fairly locked down – it was not designed to be public facing, or to expose any of its rendering functionality to the outside world. This is fairly convoluted code, and was not particularly designed with reuse in mind.

However, it would have been a VERY large job to replicate the interface construction code in the administration tool – not to mention ongoing maintenance issues if you attempted to maintain what would be essentially two versions of the same thing.

So it was decided that the best way to share the interface construction code without overly exposing our main applications assemblies was to use the InternalsVisibleTo attribute which has been provided from .NET 2.0 onwards. When you apply this attribute to an assembly (Let’s call it Assembly A) it allows you to name another assembly (Which we will call Assembly B) with which you wish to ‘share’ assembly A’s code with. So once you add a reference to A in assembly B, you can use A’s types and members just as if they were types and members of B.

  1. [assembly: InternalsVisibleTo("Planet.AssemblyB, PublicKey=0024000004<shortened>4d71f04ed3")]
  2. namespace Planet.AssemblyA
  3. {
  4.     internal static class Renderer
  5.     {
  6.         internal static void DoSomeRendering(...)
  7.         {
  8.         }   
  9.     }
  10. }
  11.  
  12. namespace Planet.AssemblyB
  13. {
  14.     using Planet.AssemblyA;
  15.     private class Previewer
  16.     {
  17.         private void DisplayPreview()
  18.         {
  19.             AssemblyA.Renderer.DoSomeRendering(...);
  20.         }
  21.     }
  22. }

It becomes a little more complex if Assembly B is strongly named – but not too much more so. You need to add Assembly B’s public key information to the InternalsVisibleTo tag in Assembly A (As shown above). You can extract this information by opening the Visual Studio Command Prompt and using sn.exe –Tp <Assembly B or any other assembly signed with the same key as B>.

So tl;dr: this is a more secure way of exposing internal code if you don’t want it shared publicly but still need to utilise it in external assemblies!

Print | posted on Friday, 21 May 2010 10:47 AM

Feedback

No comments posted yet.
Title  
Name
Email (never displayed)
Url
Comments   
Please add 8 and 3 and type the answer here: