Я реализовал очистку модулей при завершении работы приложения следующим образом.
Я создаю «сервис очистки», где модули могут регистрировать свои действия по очистке.
public interface IModuleCleanupService
{
void RegisterCleanupAction(Action action);
}
public class ModuleCleanupService: IModuleCleanupService
{
private readonly List<Action> m_cleanupActions = new List<Action>();
public void RegisterCleanupAction(Action action)
{
m_cleanupActions.Add(action);
}
public void Cleanup()
{
List<Exception> exceptions = null;
foreach (Action action in m_cleanupActions)
{
try
{
action();
}
catch (Exception ex)
{
if (exceptions==null)
exceptions = new List<Exception>();
exceptions.Add(ex);
}
}
if (exceptions != null)
throw new AggregateException(exceptions);
}
}
Тогда любой модуль может импортировать IModuleCleanupService-instance. Это можно сделать по-разному (с помощью MEF / Unity через инжекцию в конструктор или через запрос ServiceLocalor.Current)
Экземпляр службы создается в ConfigureContainer Bootstapper (здесь я использую разработанный тип MefBootstapper, но это не важно):
protected override void ConfigureContainer()
{
base.ConfigureContainer();
m_moduleCleanupService = new ModuleCleanupService();
Container.ComposeExportedValue<IModuleCleanupService>(m_moduleCleanupService);
}
Затем я добавляю метод GetDisposable в мой загрузчик, который возвращает объект IDisposable. Этот простой IDisposable-объект вызывает Cleanup для ModuleCleanupService:
public IDisposable GetDisposable()
{
return new DisposableDelegate(() => m_moduleInitializationService.Cleanup());
}
class DisposableDelegate: IDisposable
{
private readonly Action m_action;
public DisposableDelegate(Action action)
{
m_action = action;
}
public void Dispose()
{
m_action();
}
}