Сценарий: я использую Managed Extensibility Framework для загрузки подключаемых модулей (экспорта) во время выполнения на основе контракта интерфейса, определенного в отдельной dll. В моем решении Visual Studio у меня есть 3 разных проекта: хост-приложение, библиотека классов (определяющая интерфейс - «IPlugin») и другая библиотека классов, реализующая интерфейс (экспорт - «MyPlugin.dll»).
Хост ищет экспорт в своем собственном корневом каталоге, поэтому во время тестирования я создаю все решение и копирую Plugin.dll из папки bin / release библиотеки классов плагинов в каталог отладки хоста, чтобы DirectoryCatalog хоста нашел его и смог чтобы добавить его в CompositionContainer. Plugin.dll не копируется автоматически после каждой перестройки, поэтому я делаю это вручную каждый раз, когда вносил изменения в контракт / реализацию.
Однако пару раз я запускал хост-приложение без предварительного копирования (обновленного) Plugin.dll, и оно выдавало исключение во время композиции:
Unable to load one or more of the requested types. Retrieve the LoaderExceptions for more information
Это, конечно, связано с тем, что Plugin.dll, из которого он пытается импортировать, реализует другую версию IPlugin, где сигнатуры свойств / методов не совпадают. Хотя этого легко избежать в контролируемой и отслеживаемой среде, просто избегая (черт возьми) устаревших реализаций IPlugin в папке плагинов, я не могу полагаться на такие предположения в производственной среде, где могут встречаться устаревшие плагины.
Проблема в том, что это исключение эффективно сбивает все действие Compose, и экспорт не импортируется. Я бы предпочел, чтобы несоответствующие реализации IPlugin просто игнорировались, чтобы другие экспорты в каталогах, реализующие правильную версию IPlugin, по-прежнему импортировались.
Есть ли способ добиться этого? Я думаю об одном из нескольких возможных вариантов:
- Для CompositionContainer необходимо установить флаг («игнорировать неудачный импорт») до или при вызове Compose.
- Аналогичный флаг можно указать в атрибуте
<ImportMany()>
- Существует способ «зацепиться» за итерационный процесс, лежащий в основе Compose (), и иметь возможность обрабатывать каждый (неудачный) импорт индивидуально.
- Использование подписи строгого имени для поиска только импорта, реализующего текущую версию IPlugin
Идеи?