InternalsVisibleTo用于动态生成的程序集,但具有强大的命名功能

时间:2011-02-08 18:20:02

标签: c# dynamic reflection.emit strongname internalsvisibleto

我有一个使用动态代码生成来创建代理类的项目。此代理类使用项目的内部类(因此不公开实现细节),因此我将InternalsVisibleTo与我动态生成的程序集的名称一起使用。直到最近,当我的客户强制要求所有装运的程序集都有很强名称时,这种方法运行良好。

出现这个问题的原因是,为了将InternalsVisibleTo与强名称程序集一起使用,它引用的程序集也必须是强名称的,并且必须提供公钥。我遇到的问题是如何为动态生成的程序集提供强名称。这是我到目前为止所做的:

  1. 我为动态装配创建了一个新的密钥对,因此.snk可以随产品一起提供(显然我们不希望运送.snk用于签署其余的项目组件。)
  2. 我已经解压缩了PublicKey并更新了我的InternalsVisibleTo,以便为动态引用的程序集使用新的动态PublicKey。
  3. 我试图像这样签署动态生成的程序集:

        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");
    
  4. 不幸的是,这不起作用,我一直很难找到关于它应该如何工作的任何文档。有没有人知道如何签署动态生成的程序集,以便可以通过InternalsVisibleTo访问它?我可以公开必要的类,但最终会泄漏实现细节,最好留下封装。

1 个答案:

答案 0 :(得分:4)

MSDN上有一篇“How to: Use Full Signing to Give a Dynamic Assembly a Strong Name”文章,介绍如何签署使用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);