Intro
If you want to test the internals of a productive assembly you must mark the assembly with the InternalsVisibleTo-attribute. This attribute has only one constructor which needs the name of the testing assembly.
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.internalsvisibletoattribute.aspx
So this looks like:
[assembly: InternalsVisibleTo("UnlinkedObjectsRestSoe.Tests")]
Visual Studio and 3rd party plugins uses the string to mark referencing artifacts with permitted/denied hints.
Strong named assemblies
If the productive assembly is strong named you get with this (simple) style an error:
Friend assembly reference 'UnlinkedObjectsRestSoe.Tests' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.
Okay – this makes sense, because a strong named assembly could only reference strong name assemblies. So we must sign the testing project too.
And we must set some additional information in the code.
Public Key Token
In some articles is described, that you could use the public key token for the additional information. This is a wrong information! But let us go the steps I gone for a better understanding.
You could extract the public key token of your keyfile over two steps
- extract the public key from the keyfile with
sn –p <keyfile.snk> <keyfile.snk.PublicKey>
- show the public key token with
sn -t <keyfile.snk.PublicKey>
Now this public key token is set:
[assembly: InternalsVisibleTo("UnlinkedObjectsRestSoe.Tests, PublicKeyToken<"123456789abscdef">)]
The public key token must be wrapped in angle brackets, otherwise the compiler error is the same.
Furthermore for Visual Studio is only the name of the referencing assembly interesting – after the comma you could write nonsense.
Till here all works fine.
The problem came up when you reference internals from the productive assembly in your testing assembly.
The compiler throws something like:
'UnlinkedObjectsRestSoe.Artifact' does not contain a definition for 'Foo' and no extension method 'Foo' accepting a first argument of type 'UnlinkedObjectsRestSoe.Artifact' could be found (are you missing a using directive or an assembly reference?)
Public Key
Now it is time for the right way: use public key instead public key token!
To show the public key you use: sn –tp <keyfile.snk.PublicKey>
This outputs a very long key over five lines. Copy it and add the lines together (e.g. via notepad)
Next change in code the attribute line to:
[assembly: InternalsVisibleTo("UnlinkedObjectsRestSoe.Tests, PublicKey=123456789...abscdef")]
In this case without angle brackets!
Conclusion
Fine – now you have:
- correct behaviour of Visual Studio and 3rd party plugins concerning squiggles under referencing code
- a compileable productive project
- a compilable testing project