9
votes

I am trying to expose some internals to my unit test project by using:

[assembly: InternalsVisibleTo("MyTest")]

But I am getting the error:

Error 1 Friend assembly reference MyTest' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations. .../MyClass.cs...

When I assign a PublicTokenKey manually:

[assembly: InternalsVisibleTo("MyTest, PublicKeyToken=XxxxxYysakf")]

The solution builds without any error.

  1. Why do I need to include a public key token?
  2. I am not sure if I will break something in production by including the public key token.

So, what is the best and safest way to assign an public key to my Test project?

1
You shouldnt need to assign a public key token. But you need to make sure that the assembly names match.user604613
I am copy pasting the assembly names from the Assembly Name field shown in Project properties. So it should be correct, I gues..pencilCake
Alright, so i havent encountered that issue myself, but this guy here might have another option for you blog.tylerholmes.com/2008/04/…user604613
The solution builds without errors when you use PublicKeyToken, but Intellisense might give you a hint that the assembly reference couldn't be resolved.Bogdan Verbenets

1 Answers

7
votes

I am surprised that PublicKeyToken even works - on my machine it forces me to use PublicKey

  1. The reason that you need a public key token is because strongly-named assemblies can be put into the GAC - which has high trust. It would be a security hole if any assembly called 'MyTest' (that is potentially untrusted - e.g. a control in the browser) could call into the internals of a GACed assembly; it wants the public key to prevent this type of hack.

  2. This shouldn't break anything in production - even if the assembly cannot be found. This attribute is used during compile-time and not runtime.

What is the safest way?

If you are really worried about it breaking production code, remove the attribute during release builds:

#if (DEBUG || TEST)
[assembly: InternalsVisibleTo("MyTest, PublicKeyToken=XxxxxYysakf")] 
#endif

If you have a few projects that need the public key token (and you have a single key pair, which you should) you could also define a file such as AssemblyInfo.global.cs and add it as a linked file to all your projects:

class KeyTokens
{
   public const string Global = ", PublicKeyToken=XxxxxYysakf";
}

This simplifies things to (especially if you need to use the PublicKey which is really long):

#if (DEBUG || TEST)
[assembly: InternalsVisibleTo("MyTest" + KeyTokens.Global)] 
[assembly: InternalsVisibleTo("HisTest" + KeyTokens.Global)] 
[assembly: InternalsVisibleTo("TheirTest" + KeyTokens.Global)] 
#endif