This article could be entitled "every day I love you more and more", sung in the jaunty manner of the Kaiser Chiefs song, however I do mean more and not less. Let me explain.

For years (well, about 5 now, give or take a month or two) I've been using .NET, and most of that time I've been heavily into attributes. Not the XML ones I hasten to add - don't get me going, but instead the ones you get in .NET. One of my first talks about .NET was on attributes, as was a chapter in one of the books I helped with. I love 'em. One of my other favourite things is unit testing (I know, pretty strange for a developer type, but it's true). I also *love* documenting my code too.

Anyhow, I digress. One of the problems I've always had with unit testing is that the tests need to live in a separate assembly, and so anything under test has to be publicly visible outside the assembly. Not great.

Enter the [InternalsVisibleTo()] attribute. This little beauty will allow you to separate your unit tests from your code, but make it possible to call internals from another assembly. Cool!.

using System;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo ( "UnitTests" ) ]

That's all there is to it (well, nearly). When you compile the main assembly, we pickle (yes, that's the right word!) this attribute into it. Then, when you try to compile your unit tests, the compiler is clever enough to look for this attribute and emit the appropriate stuff so that you can then call you internal classes/methods. Obviously the above is a little lacking, in that I've only specified "UnitTests" as the name of the assembly. Typically you would use not only the name but also the public key token of that assembly. The text used by the attribute is an assembly name, so you can add in culture etc to the string too.

The [InternalsVisibleTo()] attribute also allows you to use it multiple times, so you could have a list of assemblies that can call your internal methods.

Now, this isn't a suggestion that you mark all your public methods internal, nor is it a suggestion that you should mark all privates as internals - use this where it makes sense, but sparingly.

For more information, see the Friend Assemblies topic on MSDN.