Как перечислить сборки в AggregateCatalog или DirectoryCatalog в MEF?

У меня есть приложение MEF (Microsoft Extension Framework), которое загружает некоторые сборки из папки. Мне нужно перечислить сборки, которые производили экспорт для моего приложения.

Один из способов сделать это - перечислить импорт, вызывающий GetExportedObject().GetType().Assembly. Но было бы чище сделать это без создания экземпляров импорта. Есть ли способ получить загруженные сборки из каталога или еще чего?

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


c# mef
person Sergey Aldoukhov    schedule 13.05.2009    source источник


Ответы (4)


AssemblyCatalog имеет свойство Assembly. У AggregateCatalog нет способа получить эту информацию напрямую - нет гарантии, что внутренние каталоги даже загружают свои детали из сборки. DirectoryCatalog не имеет такой возможности, хотя ее можно было бы добавить, если бы на то была веская причина.

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

РЕДАКТИРОВАТЬ: MEF не имеет способа получить список всех экспортов, которые были «использованы» в композиции. Вы, вероятно, могли бы написать свой собственный каталог, который возвращал бы определения частей, которые были оболочками вокруг определений частей по умолчанию, и отслеживал бы, какие части вызывали GetExportedObject. Вы можете использовать API в ReflectionModelServices, чтобы выяснить, какой тип соответствует данному определению детали из каталогов по умолчанию. Обратите внимание, что написание такого каталога, вероятно, будет непростым делом.

person Daniel Plaisted    schedule 13.05.2009
comment
Обновил вопрос, зачем мне сборки. На самом деле, даже возврат сборок DirectoryCatalog не решит мою задачу, потому что список может содержать библиотеки DLL MEF, которые не имеют ничего общего с импортом my. Если бы я мог получить сборку из экспорта без вызова GetExportedObject или получить удовлетворенные сборки импорта каким-либо другим способом ... - person Sergey Aldoukhov; 13.05.2009
comment
Я добавлю, что мне нужна такая же функциональность. Я интегрируюсь с другой системой, использующей BuildManager, и хочу добавить сборки, которые я использую с MEF, в BuildManager. - person Brian Vallelunga; 30.06.2010

Это один из способов сделать это, и он используется в Caliburn.Micro:

var aggregateCatalog = new AggregateCatalog(...);
var assemblies = aggregateCatalog.Parts
    .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
    .Distinct()
    .ToList();
person lukebuehler    schedule 10.06.2014
comment
лучший ответ! таким образом я могу продолжать использовать DirectoryCatalog и по-прежнему получать список всех сборок, которые были загружены (Части) через MEF. В приведенном выше коде я изменил AggregateCatalog на DirectoryCatalog. - person juFo; 09.02.2015
comment
Спасибо! Это избавило меня от многих раздоров. Я знал, что должен быть способ получить больше информации из этого бедного Parts списка. - person Isaac Baker; 07.10.2016

Вот мое текущее решение, которое отлично работает:

  1. Не используйте DirectoryCatalog, загружайте сборки напрямую и создавайте из них AssemblyCatalog.
  2. Используйте AssemblyCatalog.Parts, чтобы узнать, какие сборки имеют экспорт, позвольте пользователю авторизовать их.
  3. Добавляйте только авторизованные AssemblyCatalog в AggregateCatalog, который есть в композиции.
person Sergey Aldoukhov    schedule 15.10.2010

Если у вас есть доступ к источнику этих сборок, у меня есть альтернативное решение для добавления сборок по одной. Вы можете создать интерфейс под названием IModule и сделать его обязательным для всех ваших сборок для его экспорта. Затем вы можете импортировать их все в свой загрузчик:

[ImportMany]
public List<IModule> Modules { get; set; }

Этот список будет содержать список всех классов модулей, через которые вы можете получить доступ к сборке:

var module1 = Logic.Instance.Modules[0];
var fullename = module1.GetType().Assembly.FullName;
person Aidin    schedule 31.10.2013