Как создать и использовать справочную сборку только для метаданных .NET? - PullRequest
24 голосов
/ 26 сентября 2011

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

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

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

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

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

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

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

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

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

Ответы [ 4 ]

9 голосов
/ 26 сентября 2011

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

[assembly: ReferenceAssembly]

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

Assembly.ReflectionOnlyLoad ()

или

Assembly.ReflectionOnlyLoadFrom ()


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

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

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

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


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

3 голосов
/ 19 августа 2012

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

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

(я попробовал его на полной платформе XNA Framework, и он работает на время ...)

2 голосов
/ 26 сентября 2011

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

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

1 голос
/ 26 сентября 2011

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

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

ГГМВ

...