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

Элемент управления WPF, исключающий исключение "ресурса, идентифицированного отсутствием URI"

При загрузке плагина и попытке создания элемента управления "XYZ" приложение выдает следующее исключение:

"Компонент" XYZ "не имеет ресурс, идентифицированный URI" /ThePluginAssembly;component/XYZ.xaml" по методу InitializeComponent() в конструктор UserControls.

Ключевыми моментами являются:

  • Пользовательский элемент управления находится в сборке плагинов

  • Я пытаюсь создать usercontrol изнутри сборки плагинов

  • Плагины расположены в том же каталоге, что и основное приложение

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

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

Мои вопросы:

1) В чем причина того, что WPF пытается разрешить URI для загрузки моего элемента управления?

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

Любой комментарий или ссылка будут полезны.

Спасибо за ваш интерес.

Изменить: Та же проблема, что и Фил: Как заставить WPF использовать URI ресурсов, которые используют сильное имя сборки? Argh!

4b9b3361

Ответ 1

Единственный способ сделать это - включить информацию о версии в свой URI, чтобы загрузчик XAML мог различать правильный тип. Эта статья MSDN объясняет формат URI пакета, а часть версии имеет это описание:

; Version [optional]: версия ссылочной сборки, которая содержит файл ресурсов. Это используется, когда загружаются две или более ссылочные сборки с таким же коротким именем.

Итак, вы хотите использовать одно из следующих значений:

/ThePluginAssembly;v1.0.0.0;component/XYZ.xaml
/ThePluginAssembly;v1.1.0.0;component/XYZ.xaml

Ответ 2

попробуйте использовать Assembly.LoadFrom() вместо Assembly.Load() или Assembly.LoadFile().

У меня была та же проблема: я загружал сборки с помощью Assembly.LoadFile(). После поиска дней я обнаружил, что Assembly.LoadFile() и Assembly.Load() устарели. Оба метода создают проблемы во время выполнения. Поэтому я использовал Assembly.LoadFrom(), и он сработал.

Ответ 3

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

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

Проверьте все ссылки на сборку из вашего решения и установите для параметра "Спецификация версии" значение false.

Если сборка подключается из другого решения, и вы используете разные версии сборки для debug/release или для x86/x64, тогда отредактируйте файлы .csproj, ссылающиеся на сборку, и установите ссылочный путь, как в этот пример.

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

Убедитесь, что Pack URI ресурсам: "Пакет://Применение:,,/ReferencedAssembly; компонент/подпапки/ResourceFile.xaml"

Ответ 4

До сих пор лучшее решение, к которому я добрался, изменяет имя моей плагины dll в свойствах проекта и делает его специфичным для версии.

Итак, если изначально это был "prod.myplugin", теперь я сделал это "prod.myplugin_300d3". После изменения свойств проекта, когда я перестраиваю проект, компилятор регенерирует файлы .g.cs, и теперь он имеет версию в URI (она отображается как /prod.myplugin_300d3;component/XYZ.xaml) и, таким образом, делает мой идентификатор URI в разных версиях.

Я все еще ищу лучшее, автоматическое решение, в котором я мог бы изменить конфигурацию MSBuild: Compile.

Ответ 5

Скопируйте все файлы из папки bin в отдельную папку из всех проектов, находящихся в вашем решении, и удалите папку отладки и выпуска из папки bin каждого проекта. Это решило проблему дизайнера для меня.

Помните, что при компиляции в следующий раз все файлы снова вернутся. Таким образом, вы должны иметь некоторую script в пост-сборке, чтобы скопировать в другую папку и удалить файлы из папки bin.