C# Assembly.LoadFrom с динамическим AssemblyResolve
Я немного застрял с динамически загружаемыми плагинами:
Теория: (Плагин) Dlls в определенной папке:
foreach(string path in Directory.GetFiles(...))
{
Assembly myPlugin = Assembly.LoadFrom(path);
foreach(Type type in myPlugin.GetTypes().Where(t => typeof(myPluginBaseClass).isAssignableFrom(t)))
{
Activator.CreateInstance(type);
}
}
Все идет нормально. Теперь есть проблемы с дополнительными ссылками в этих сборках, которые могут быть решены catch(ReflectionTypeLoadException)
(чтобы удалить все нулевые типы) и AppDomain.CurrentDomain.AssemblyResolve += ...
(чтобы вручную найти эти недостающие библиотеки)
Теперь возникает проблема: упомянутые отсутствующие сборки являются специфическими для каждого реализованного плагина, поэтому мне нужно индивидуальное поведение поиска, реализованное в каждом плагине. Мои идеи / решения до сих пор:
- Наличие глобального списка всех возможных каталогов DLL в моем главном приложении -> глупо, потому что это не позволит добавлять дополнительные плагины без изменения основного кода приложения
- Наличие (не статичного) словаря конкретных путей к DLL в каждом плагине -> может быть вызвано
myPluginBaseClass
использование виртуального / абстрактного; Но не могут быть доступны до создания экземпляра (где теAssemblyResolveEvents
уволены), поэтому не полезно - Наличие (статического) словаря конкретных путей к DLL в каждом плагине -> может быть прочитано до создания экземпляра с помощью Reflection, но я не могу добавить это к своему
myPluginBaseClass
как определенный шаблон, поэтому возможны ошибки - Создание отдельного домена для каждого плагина и позволить им обрабатывать свои собственные
AssemblyResolveEvent
-> Но как?
Я надеюсь, что вы можете помочь!
Заранее спасибо! Робин
1 ответ
Создание домена кажется адекватным решением для шаблона плагина.
Вам на самом деле не нужно определять AssemblyResolve, вы можете просто настроить каталог, в котором AppDomain может найти зависимости.
https://msdn.microsoft.com/fr-fr/library/system.appdomainsetup.applicationbase(v=vs.110).aspx