Хорошо, я отвечу на свой вопрос.
Я не нашел доказательств того, что API-интерфейсы System.Reflection.Emit
могут создавать сборки, ссылающиеся на другую версию mscorlib
, чем та, которая используется в текущем процессе. Действительно, API, которые принимают параметры System.Type
и другие объекты отражения, предположительно добавляют ссылку на результат запроса своего свойства Type.Assembly
, что соответствует используемой версии mscorlib
.
Однако портативные библиотеки классов не отличаются от того, что генерирует System.Reflection.Emit
, поэтому после сбоя можно исправить сборки, чтобы «сделать их переносимыми». Отказа от ответственности: это требует знакомства с форматом PE файла и может иметь непредсказуемые побочные эффекты, но это работает для меня:
При создании сборки, используйте AssemblyBuilder.SetCustomAttribute
, чтобы добавить этот атрибут к сборке:
[System.Runtime.Versioning.TargetFrameworkAttribute(".NETPortable,Version=v4.0,Profile=Profile136", FrameworkDisplayName = ".NET Portable Subset")]
Это где он получает схематичен: после того, как называется AssemblyBuilder.Save
, откройте файловый поток для чтения/записи сгенерированной сборки, пройти через PE, COFF, COM, CLI и таблицы метаданных заголовки, чтобы найти строку AssemblyRef
таблицы за mscorlib
. Измените ссылочную версию mscorlib
на номер 2.0.5.0
, добавьте 0x100
к своим флагам («перенастраиваемым») и обновите свой токен с открытым ключом до 0x7CEC85D7BEA7798E
.
Обратите внимание, что если вы используете другие сборки фреймов, возможно, вам потребуется также исправить их ссылки (я не проверял это). В противном случае, вуаля! Теперь сборка переносима и может использоваться, например, в проекте Windows Phone.
(... или просто использовать Mono.Cecil
/IKVM.Reflection
...)
Edit: Код я использовал можно найти on github. Это огромный взлом, поэтому обычные заявления об отказе от ответственности применяются на ваших собственных рисках.
Возможно, вы также захотите взглянуть на IKVM.Reflection, это позволит вам настроить таргетинг на другую версию фреймворка, чем текущая. – svick
@svick Спасибо, я не знал, что IKVM имеет публичный API Emit. На первый взгляд, Mono.Cecil кажется лучше разработан. Есть ли какие-то причины, которые я должен предпочесть IKVM.Reflection? – Trillian
API IKVM Reflection намеренно очень похож на нормальное отражение.Итак, если вы уже знаете это, вы сможете начать использовать его очень быстро. – svick