Подтвердить что ты не робот

Как создать и использовать только "Сборочную сборку" только для метаданных?

Начиная с версии 3.0,.NET устанавливает множество различных "сборочных сборок" в разделе C:\Program Files\Reference Assemblies\Microsoft.... для поддержки разных профилей (например, профиль клиента .NET 3.5, профиль Silverlight). Каждая из них является подходящей сборкой .NET, которая содержит только метаданные - не IL-код, и каждая сборка помечена ReferenceAssemblyAttribute. Метаданные ограничены теми типами и членами, доступными в соответствии с применимым профилем, - что как intellisense показывает ограниченный набор типов и членов. Ссылочные сборки не используются во время выполнения.

Я немного узнал об этом из этого сообщения в блоге.

Я хотел бы создать и использовать такую ​​ссылочную сборку для своей библиотеки.

  • Как создать сборку только для метаданных - есть ли какой-нибудь флаг компилятора или постпроцессор ildasm?
  • Существуют ли атрибуты, которые управляют тем, какие типы экспортируются в разные "профили"?
  • Каким образом разрешение ссылочной сборки во время выполнения - если бы у меня была ссылочная сборка, присутствующая в моей директории приложений, а не в "реальной" сборке, а не в GAC вообще, прощупывание продолжалось бы и событие AssemblyResolve, чтобы я может поставлять фактическую сборку во время выполнения?

Любые идеи или указатели на то, где я мог бы узнать больше об этом, будут очень признательны.

Обновление. Оглядываясь немного, я вижу, что сборщики ссылок .NET 3.0, похоже, имеют некоторый код, а атрибут Reference Assembly был добавлен только в .NET 4.0. Таким образом, поведение может немного измениться с новой средой выполнения.

Почему? Для моей библиотеки Excel-DNA (http://exceldna.codeplex.com) я создаю однодоменную надстройку .xll, упаковывая ссылочные сборки в файл .xll как Ресурсы. Упакованные сборки включают пользовательский код надстройки, а также управляемую библиотеку Excel-DNA (на которую может ссылаться сборка пользователя).

Это звучит довольно сложно, но в большинстве случаев он прекрасно работает - надстройка представляет собой один небольшой файл, поэтому нет установки проблем с дистрибутивом. Я сталкиваюсь с (не неожиданными) проблемами из-за разных версий - если в качестве файла старой управляемой библиотеки Excel-DNA есть старая версия, среда выполнения загрузит это вместо упакованного (я никогда не получаю возможность помешать загрузка).

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

4b9b3361

Ответ 1

Чтобы создать ссылочную сборку, вы должны добавить эту строку в свой файл AssemblyInfo.cs:

[assembly: ReferenceAssembly]

Чтобы загрузить других, вы можете ссылаться на них как обычно из ваших проектов проекта VisualStudio или динамически во время выполнения, используя:

Assembly.ReflectionOnlyLoad()

или

Assembly.ReflectionOnlyLoadFrom()


Если вы добавили ссылку на сборку метаданных/ссылок, используя VisualStudio, то intellisense и создание вашего проекта будут работать нормально, однако если вы попытаетесь выполнить свое приложение против одного, вы получите сообщение об ошибке:

System.BadImageFormatException: не удается загрузить контрольную сборку для выполнения.

Итак, ожидание заключается в том, что во время выполнения вы заменили бы в реальной сборке, имеющей одну и ту же подпись метаданных.

Если вы динамически загрузили сборку с помощью Assembly.ReflectionOnlyLoad(), вы можете выполнять только все операции отражения против нее (читайте типы, методы, свойства, атрибуты и т.д., но не можете динамически вызывать их).


Мне интересно, что вы используете для создания сборки только для метаданных. Мне никогда не приходилось делать это раньше, и мне было бы интересно узнать, нашли ли вы для них интересное использование...

Ответ 2

Если вы по-прежнему заинтересованы в этой возможности, я создал вилку проекта il-repack на основе Mono.Cecil, который принимает аргумент командной строки "/meta", чтобы создать сборку только для метаданных для публичных и защищенных типы.

https://github.com/KarimLUCCIN/il-repack/tree/xna

(Я попробовал это на полной платформе XNA Framework и ее рабочем афайке...)

Ответ 3

Да, это ново для .NET 4.0. Я уверен, что это было сделано, чтобы избежать неприятных проблем с версиями в пакетах обновления .NET 2.0. Лучший пример - перезагрузка WaitHandle.WaitOne(int), добавленная и документированная в SP2. Популярная перегрузка, потому что она позволяет избежать угадывания правильного значения для * exitContext в перегрузке WaitOne (int, bool). Проблема в том, что программа бомбит, когда она запускается на версии 2.0, которая старше SP2. Кроме того, изолирование эталонных сборок гарантирует, что это не повторится.

Я думаю, что эти сборки ссылок были созданы, начиная с копии скомпилированных сборок (как это было сделано в предыдущих версиях) и запускали их через инструмент, который удаляет IL из сборки. Однако этот инструмент недоступен для нас, ничего не найдено в подкаталоге bin/netfx 4.0 под Windows 7.1 SDK, который мог бы это сделать. Не совсем инструмент, который часто используется, поэтому, вероятно, это не качество продукции:)

Ответ 4

Возможно, вам повезло с Cecil Library (от Mono); Я думаю, что реализация позволяет ILMerge функциональность, она может так же хорошо писать метаданные только сборки.

Я просмотрел базу кода (документация разрежена), но пока не найдено никаких очевидных подсказок...

YYMV