Ошибка обновления подключаемого модуля MEF
Проблема
Мой код MEF не обновляет сборки во время выполнения, из папки, связанной с каталогом DirectoryCatalog. Плагины загружаются во время выполнения succesffully, но когда я обновляю dll и вызываю Refresh в DirectoryCatalog, сборки не обновляются.
Фон
Я создаю dll, у которого есть контейнер MEF, и использует DirectoryCatalog для поиска локальной папки плагина. Я вызываю эту dll в настоящее время из простой WinForm, которая настроена с помощью отдельного проекта для использования ShadowCopy, поэтому я могу перезаписать DLL в моей папке плагина. Вместо использования FileWatcher для обновления этой папки я подвергаюсь публичному методу, который вызывает обновление в DirectoryCatalog, поэтому я могу обновлять сборки по желанию, а не автоматически.
Код
базовый класс создает экземпляры каталогов и контейнеров MEF и сохраняет их как переменные класса для ссылочного доступа позже
public class FieldProcessor
{
private CompositionContainer _container;
private DirectoryCatalog dirCatalog;
public FieldProcessor()
{
var catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the TestPlugin class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestPlugin).Assembly));
dirCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "Plugin\\");
catalog.Catalogs.Add(dirCatalog);
//Create the CompositionContainer with the parts in the catalog
_container = new CompositionContainer(catalog);
}
public void refreshCatalog()
{
dirCatalog.Refresh();
}
} ...
вот плагин, который я пытаюсь перезаписать. Мой тест обновления - это то, что возвращенные жало были выведены в текстовое поле, я меняю строки, которые плагин возвращает, перестраивает и копирует в папку плагина. Но он не обновляется для запуска приложения, пока я не закрою и не перезагрузим приложение.
[Export(typeof(IPlugin))]
[ExportMetadata("PluginName", "TestPlugin2")]
public class TestPlugin2 : IPlugin
{
public IEnumerable<IField> GetFields(ContextObject contextObject, params string[] parameters)
{
List<IField> retList = new List<IField>();
//Do Work Return Wrok Results
retList.Add(new Field("plugin.TestPlugin2", "TestPluginReturnValue2"));
return retList;
}
}
Изменить
Операция импорта
[ImportMany(AllowRecomposition=true)]
IEnumerable<Lazy<IPlugin, IPluginData>> plugins;
Исследование
Я провел довольно обширные исследования и повсюду в статьях и образцах кода, которые, как представляется, являются ответом: добавить DirectoryCatalog в контейнер и сохранить ссылку в этом каталоге, а затем вызвать Refresh on this ссылка, после добавления нового плагина, и он обновит сборки... которые я делаю, но не показывает обновленный вывод из новой плагины плагинов.
Запрос
Кто-нибудь видел эту проблему или знал, что может быть причиной моих проблем с сборками, которые не обновляются во время выполнения? Любая дополнительная информация или понимание будут оценены.
Разрешение
Благодаря Panos и Stumpy за их ссылки, которые привели меня к решению моей проблемы. Для будущих искателей знаний моя основная проблема заключалась в том, что метод Refresh не обновляет сборки, когда новая сборка имеет то же самое имя сборки, что и перезаписываемая dll. Для моей POC я только что протестировал перестройку с датой, прикрепленной к имени сборки, и все остальное же, и это сработало как шарм. их ссылки в комментариях ниже, были очень полезны и рекомендованы, если у вас есть такая же проблема.
Ответы
Ответ 1
Вы установили параметр AllowRecomposition
в свой атрибут импорта?
AllowRecomposition
Gets or sets a value that indicates whether the property or field will be recomposed when exports with a matching contract have changed in the container.
http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.95).aspx
изменить:
DirectoryCatalog не обновляет сборки, только добавляет или удаляет:
http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx
для работы:
fooobar.com/info/539660/...