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");
    

К сожалению, это не работает, и мне было очень трудно найти какую-либо документацию о том, как это должно работать. Кто-нибудь знает, как подписать динамически сгенерированную сборку, чтобы ей можно было предоставить доступ через InternalsVisibleTo? Я могу просто сделать необходимые классы общедоступными, но это приведет к утечке деталей реализации, которые лучше оставить инкапсулированными.


person Dan Bryant    schedule 08.02.2011    source источник
comment
Какой именно тип генерации динамического кода вы используете? Отражение. КодДом? Сесил?   -  person R. Martinho Fernandes    schedule 08.02.2011
comment
Генерация осуществляется через Reflection.Emit.   -  person Dan Bryant    schedule 08.02.2011
comment
Moq делает это, вы могли бы спросить его исходный код ... ;-)   -  person Lucero    schedule 08.02.2011


Ответы (1)


Существует "Как использовать полную подпись для присвоения динамической сборке строгого имени "статья в MSDN, в которой показано, как подписывать сборки, созданные с помощью 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);
person R. Martinho Fernandes    schedule 08.02.2011
comment
Спасибо, это именно то, что мне нужно. Не уверен, почему я не смог найти его при предыдущих поисках. Возможность хранить ключ как встроенный ресурс также является приятным дополнительным преимуществом. - person Dan Bryant; 08.02.2011
comment
@Dan: Я только что искал MSDN Reflection.Emit Signing в Google;) Первый результат содержит серию инструкций и пошаговых руководств, включая это. - person R. Martinho Fernandes; 08.02.2011