LP on .NET

October 14, 2009

Making Internals Available to Other Assemblies

Filed under: .NET,C#,Software Development — Larry Parker @ 7:35 am

Sometimes it’s desirable to make internal types and members available to other assemblies.  A good example of this is when writing unit tests.

I have to confess that sometimes I would temporarily make a method public so I could more easily unit test it.  Or I would generate a private accessor, but that can be annoying when you refactor code later on.

But aside from unit testing, I never had a good reason to make internals available to other assemblies.  That recently changed when I was coding a serializable type that looks something like this:

[DataContract]
public class SessionResponse
{
    [DataMember]
    public SessionState SessionState { get; internal set; }

    [DataMember]
    public Guid SessionKey { get; internal set; }
}

The SessionState and SessionKey properties are set by the server, so it makes sense for them to be readonly on the client.  The problem is that the code on the server side that sets these properties is in a different assembly from where the serializable type is defined.

This results in a compilation error since the “internal” modifier restricts access to that assembly only.  What we need is to make these assemblies “friends”.  You can read more about friend assemblies on MSDN here.

An assembly can be made a friend of another by marking it with the InternalsVisibleTo assembly attribute.

For example, in the AssemblyInfo.cs file of the assembly that contains the SessionResponse type, I added the following:

[assembly: InternalsVisibleTo("MyServerAssemblyName, PublicKey=0047…")]

My server assembly already had a strong name, so I didn’t have to generate one.  But the problem was obtaining its public key so I could fill in the PublicKey value in the InternalsVisibleTo attribute.

I found a helpful blog entry here that shows how to do it.  You basically need to open up a Visual Studio command prompt, and then use the .NET Strong Name Utility to extract the public key from your strong name key file:

sn.exe -p MyStrongNameKey.snk MyStrongNameKey.PublicKey

sn.exe -tp MyStrongNameKey.PublicKey

Be sure to remove the line breaks from the public key that is displayed in the console before pasting it into the InternalsVisibleTo attribute.

And that’s it!  Now the server assembly can set the SessionState and SessionKey properties, and these properties will be readonly on the client.

Hope this helps.

Blog at WordPress.com.