共用方式為


Friend Assemblies in .NET

Alsalam alikom wa r7amat Allah wa barakatoh (Peace upon you..)

Long story short, you have AssemblyA (with source code) and AssemblyB… you want AssemblyB to be able to access internal members (types, data, methods.. etc) of AssemblyA…
You can of course do that through Reflection but come on, it’s not a descent way to do it.. right??

.Net framework offers an attribute called InternalsVisibleToAttribute [MSDN Link]. It works on .NET 2.0 and above. An example grabbed from MSDN:

    1: // AssemblyA.dll
    2: using System.Runtime.CompilerServices;
    3: using System;
    4:  
    5: [assembly:InternalsVisibleTo("AssemblyB")]
    6:  
    7: // internal by default
    8: class Class1 
    9: {
   10:     public void Test() 
   11:     {
   12:         Console.WriteLine("Class1.Test");
   13:     }
   14: }
   15:  
   16: // public type with internal member
   17: public class Class2 
   18: {
   19:     internal void Test() 
   20:     {
   21:         Console.WriteLine("Class2.Test");
   22:     }
   23: }

This way, you can easily use Class1 and Class2.Test from AssemblyB code (obviously after adding reference to AssemblyA).
I had 2 questions in mind after reading this,

  1. This can be some sort of a hack, I simply create another asesmbly that replaces your AssemblyB and violla, I’ve access to your internal members…
    A: You can include the public token key for AssemblyB in InternalsVisibleTo constructor
  2. Can I selectively determine what classes (types) are visible to AssemblyB?

.NET offers a class called StrongNameIdentityPermission [MSDN Link] Which can solve both of these problems actually.

I’ll not go into details for how to do it, but let me state what can you do using this class..
You can require that calling assemblies (e.g AssemblyB) must be strongly signed using a private key you provide.. (Imagine you are building a multi-tier application and you don’t want anybody else to just call your public classes…)

StrongNameIdentityPermission works only on public classes, while InternalsVisibleToAttribute works on assembly level.

One last thing, it’s actually kind of funny.. InternalsVisibleTo constructor has 2 overloads (only in .NET3.5), the second accepted named parameter named AllIntenalsVisible (bool) which gave me hope that I can somehow selectively choose what to make visible… but… here is what I found in MSDN Documentation:

This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.

Catch you later…

Comments