从WPF中的PRISM获取已加载模块的列表

时间:2009-12-03 06:09:19

标签: wpf prism

我有一个建立在PRISM之上的WPF应用程序。

当用户尝试关闭应用程序时,我需要检查任何已加载视图的脏状态。

我希望枚举已加载模块的列表并依次询问它们是否可以退出并保存任何更改,但我无法找到已加载模块的引用列表。

我能找到的最接近的是IModuleCatalog,它给出了一个模块列表,但不是实际的对象引用了这些模块

关于我如何做到这一点的任何建议?

提前致谢

伊恩

4 个答案:

答案 0 :(得分:4)

您是否考虑过复合命令,而不是您当前的方法?看起来您的观点应该参与应用程序的关闭,而不是模块逻辑的一些中心位置。

此示例(称为命令样本,我认为很好说......它是非常命令)说明了“全部保存”,这与您的“全部关闭”非常相似(基本上你在做什么)。这里很棒的是,这是功能,因为你不需要自己构建:http://msdn.microsoft.com/en-us/library/dd458890.aspx

答案 1 :(得分:2)

我已经通过以下方式实现了模块清理应用程序关闭。

我创建了“清理服务”,模块可以在其中注册清理操作。

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)

服务的实例是在Bootstapper的ConfigureContainer中创建的(这里我使用的是MefBootstapper设备类型,但这并不重要):

protected override void ConfigureContainer()
{
    base.ConfigureContainer();

    m_moduleCleanupService = new ModuleCleanupService();
    Container.ComposeExportedValue<IModuleCleanupService>(m_moduleCleanupService);
}

然后我将GetDisposable方法添加到我的bootstapper,它返回IDisposable-object。 IDisposable-object简单调用ModuleCleanupService上的Cleanup:

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();
    }
}

答案 2 :(得分:1)

根据Shrike的回答,我使用类似的解决方案,通过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
}

当应用程序即将完成时,bootstrapper发布此事件:

// 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);
}

答案 3 :(得分:0)

如果您要做的是获取所有已加载模块的现有实例,您可以执行以下操作:

  1. 从Unity容器中获取IServiceLocator的现有实例。
  2. 对于状态为ModuleInfo的模块目录中的Initialized的每个实例,使用serviceLocator.GetInstance(moduleInfo.ModuleType)
  3. 获取模块实例