Reputation: 27515
I have a project that uses dynamic code generation to create a proxy class. This proxy class makes use of internal classes of the project (so that implementation details are not exposed) and so I use InternalsVisibleTo with the name of my dynamically generated assembly. This worked fine until recently, when my client imposed the requirement that all shipped assemblies be strong-named.
The issue arises because, in order to use InternalsVisibleTo with a strong-named assembly, the assemblies it references must also be strong-named and you must provide a public key. Where I'm getting stuck is how to provide a strong name for the dynamically generated assembly. Here is what I've done so far:
I've attempted to sign the dynamically-generated assemblies like this:
var name = new AssemblyName("ProxyBuilderAssembly");
var attributes = new CustomAttributeBuilder[1];
attributes[0] =
new CustomAttributeBuilder(typeof(AssemblyKeyFileAttribute).GetConstructor(new[] {typeof(string)}),
new object[] {"Dynamic.snk"});
_assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, attributes);
_module = _assembly.DefineDynamicModule("ProxyBuilderAssembly", "ProxyBuilderAssembly.dll");
Unfortunately this is not working and I have been having a very hard time finding any documentation on how this should work. Does anybody know how to sign a dynamically generated assembly so that it can be given access via InternalsVisibleTo? I can just make the necessary classes public, but that ends up leaking implementation details that would be better left encapsulated.
Upvotes: 4
Views: 1923
Reputation: 234644
There is a "How to: Use Full Signing to Give a Dynamic Assembly a Strong Name" article on MSDN that shows how to sign assemblies generated with Reflection.Emit.
StrongNameKeyPair kp;
// Getting this from a resource would be a good idea.
using(stream = GetStreamForKeyPair())
{
kp = new StrongNameKeyPair(fs);
}
AssemblyName an = new AssemblyName();
an.KeyPair = kp;
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
Upvotes: 5