Я противостою грозной головоломке.Вот моя ситуация:
Я создаю приложение с помощью инфраструктуры плагинов.Существует базовый класс плагинов, который должны расширяться всеми плагинами.В той же сборке у меня есть вспомогательный класс, который сериализует и десериализует классы.Это универсальный класс, и он используется повсеместно.Структура выглядит следующим образом:
MyApp.dll
|_ App.cs
|_ HelperCollection.cs
|_ PluginBase.cs
MyPlugin.dll
|_MyPlugin.cs (this extends PluginBase)
|_Foo.cs
Проблема
Моя проблема заключается в загрузке и блокировке файлов сборки.Требование приложения заключается в том, что Плагины могут быть перезаписаны в любое время.Если это так, их необходимо перезагрузить.Кажется, лучший способ загрузить сборку, чтобы она не была заблокирована (то есть я могу перезаписать ее или удалить, пока приложение еще работает), это:
byte[] readAllBytes = File.ReadAllBytes("MyPlugin.dll");
Assembly assembly = Assembly.Load(readAllBytes);
Загрузка сборки плагина работает простохорошо, никаких проблем нет.Я получаю исключение, когда из MyPlugin.cs , который находится в сборке плагина, я пытался использовать HelperCollection
для десериализации.Примером может быть что-то вроде этого:
// HelperCollection uses XmlSerializer under the covers
List<Foo> settingCollection = HelperCollection<Foo>.Deserialize("mysettings.xml");
Он взрывается и выбрасывает InvalidCastException
, говоря, что это "Unable to cast object of type 'List[Foo]' to 'List[Foo]'"
.После долгих исследований я наконец нашел причину .Он загружается в контексте привязки LoadNeither .
Когда загружено Foo
(из MyPlugin.dll ), оно находится в контексте привязки LoadNeither
, тогда как сборка, содержащая тип для преобразования типа (в моем случае, )MyApp.dll ) загружается в контексте по умолчанию.Таким образом, даже если они имеют одинаковое имя, они не считаются одним и тем же типом.Он делает это, потому что я использую Assembly.Load(byte[])
.
Вопросы
Как я могу обойти это?Как можно,
- загрузить сборку и не блокировать файл, и
- предоставить правильный контекст привязки, чтобы я мог приводить объекты, находящиеся в загруженной сборке.
Извините за стену текста, просто хотел получить всю необходимую информацию там.