Получение списка загруженных модулей из PRISM в WPF - PullRequest
3 голосов
/ 03 декабря 2009

У меня есть приложение WPF, созданное поверх PRISM.

Когда пользователь пытается закрыть приложение, мне нужно проверить грязный статус всех загруженных представлений.

Я надеялся перечислить список загруженных модулей и по очереди спросить их, можно ли выйти и сохранить какие-либо изменения, но у меня возникают проблемы с поиском списка ссылок на загруженные модули.

Самым близким, что я смог найти, был IModuleCatalog, который дает мне список модулей, но не фактический объект ссылается на эти модули

Любые предложения о том, как я могу это сделать?

Заранее спасибо

Ian

Ответы [ 4 ]

4 голосов
/ 03 декабря 2009

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

Этот образец (называемый Commanding Sample, который, я думаю, здорово сказать ... он очень командующий) иллюстрирует «Save All», которое очень похоже на ваше «Close All» (в основном, что ты делаешь). Самое замечательное в том, что это функциональность, которую не нужно создавать самому: http://msdn.microsoft.com/en-us/library/dd458890.aspx

2 голосов
/ 25 августа 2010

Я реализовал очистку модулей при завершении работы приложения следующим образом.

Я создаю «сервис очистки», где модули могут регистрировать свои действия по очистке.

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();
    }
}
1 голос
/ 27 апреля 2012

Согласно ответу Шрайка, я использую аналогичное решение для отправки событий IEventAggregator.

Во-первых, у меня есть простое определение события, которое называется ModulesDisposeRequested:

public class ModulesDisposeRequested : CompositePresentationEvent<object> { }

Тогда все модули, которые необходимо утилизировать, подписываются на это событие:

// Module constructor
public ModuleA(IEventAggregator eventAggregator) {
   var evnt = eventAggregator.GetEvent<ModulesDisposeRequested>();
   if (evnt != null)
      evnt.Subscribe(OnModulesDisposeRequested);
}

private void OnModulesDisposeRequested(object payload) {
   // cleanup current module
}

Когда приложение заканчивается, загрузчик публикует это событие:

// Overring in App.xaml.cs
protected override void OnExit(ExitEventArgs e) {
   var eventAggregator = _bootstrapper.Container.Resolve<IEventAggregator>();
   var evnt = eventAggregator.GetEvent<ModulesDisposeRequested>();
   if (evnt != null)
      evnt.Publish(null);

   base.OnExit(e);
}
0 голосов
/ 04 декабря 2009

Если вы хотите получить существующий экземпляр всех загруженных модулей, вы можете сделать следующее:

  1. Получить существующий экземпляр IServiceLocator из контейнера Unity.
  2. Для каждого экземпляра ModuleInfo в каталоге модулей, где состояние Initialized, получите экземпляр модуля с помощью serviceLocator.GetInstance(moduleInfo.ModuleType)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...