Prism和IEventAggregator:加载模块时遇到麻烦

时间:2014-09-03 12:14:16

标签: c# wpf prism mef bootstrapper

我实际上正在使用WPF,MEF和Prism开展项目。当我启动应用程序时,我需要从容器中导出一个模块,以便在显示主窗口之前打开配置窗口。因此代码是这样的:

        protected override void OnStartup(StartupEventArgs e)
        {       base.OnStartup(e);
                Bootstrapper bootstrapper = new Bootstrapper();
                bootstrapper.Run();

                var window = bootstrapper.statcontainer.GetExport<Configshell>();
                var configview = bootstrapper.statcontainer.GetExport<Module.Module1.View.ConfigView>();
                window.Value.Show();
                Keyboard.Focus(configview.Value.ok_button); }

其中bootstrapper.statcontainer是一个公共CompositeContainer(在CreateContainer-Method中使用MEFBootstrapper的“Maincontainer”分配)。我用它在启动时导出模块。 现在在GetExport()中,我得到以下第一次机会异常抛出:

  

在先决条件导入之前无法调用GetExportedValue'MyApp.Module.Module2.ViewModels.Module2_Functions..ctor(Parameter =“C_Aggregator”,ContractName =“Microsoft.Practices.Prism.PubSubEvents.IEventAggregator”)'已设置。< / p>

这就是ctor的样子:

    [Import]
    public IEventAggregator Configaggregator;

    [ImportingConstructor]
    public Module2_Functions(IEventAggregator C_Aggregator)
    {
        this.Configaggregator = C_Aggregator;
        Configaggregator.GetEvent<FromConfigWindow>();
        FromConfigWindow.Instance.Subscribe(receiveStatusFromConfigWindow);
        Configaggregator.GetEvent<ToConfigWindow>();
    }

我正在使用EventAggregator发布配置并在另一个模块中使用相同的ctor。令人困惑的是,它一直有效,直到我向该ViewModel添加了另一个完全独立的导入。以下是ConfigwindowViewModel的ctor的样子:

    [ImportingConstructor]
    public ConfigVM(IEventAggregator C_aggregator)
    {
        this.Configaggregator = C_aggregator;
        Configaggregator.GetEvent<ToConfigWindow>();
        ToConfigWindow.Instance.Subscribe(actualizeCompStatus);
        Configaggregator.GetEvent<FromConfigWindow>();
    }

    [Import]
    public IEventAggregator Configaggregator;

这两个事件看起来像这样,两个事件都已经工作到2天前了; - )

[Export]
public class FromConfigWindow : PubSubEvent<Int16> 
{
    private static readonly EventAggregator _eventAggregator;
    private static readonly FromConfigWindow _event;

    static FromConfigWindow()
    {
        _eventAggregator = new EventAggregator();
        _event = _eventAggregator.GetEvent<FromConfigWindow>();
    }

    public static FromConfigWindow Instance
    {
        get { return _event; }
    }
}
[Export]
public class ToConfigWindow : PubSubEvent<Int16>
{
    private static readonly EventAggregator _eventAggregator;
    private static readonly ToConfigWindow _event;

    static ToConfigWindow()
    {
        _eventAggregator = new EventAggregator();
        _event = _eventAggregator.GetEvent<ToConfigWindow>();
    }

    public static ToConfigWindow Instance
    {
        get { return _event; }
    }
}

所以最后问题在我看来,因为EventAggregator没有得到实例化,因此异常被抛出。但是我该如何解决这个问题呢?或者我在构造函数中的聚合器链接中做错了什么?

我已经尝试使用[Import]属性修改所有构造函数参数,这也引发了相同的异常,或者从ViewModel中的IEventAggregator Configaggregator对象中删除所有[Import]属性。

问题与this link here类似,但在我的情况下,Prism框架中的EventAggregator会发生。

请告诉我是否应该为您提供更多部分代码。

2 个答案:

答案 0 :(得分:1)

我不确定您为什么要导出PubSubEvents或在其中保留对静态新EventAggregator的引用。你应该只使用一个EventAggregator的实例(在这个例子中)你将从你的容器中获取(Prism会把它放在你的身上)。

你应该回到基础并阅读优秀的Prism documentation。第9节“在松散耦合的组件之间进行通信”,以获取EventAggregator和PubSubEvents的概述。

如果你想创建一个模拟你遇到的问题的裸骨项目并将其上传到某个地方,我很乐意为你看一下。

答案 1 :(得分:1)

看起来错误是因为在开始对它们进行操作之前,您还没有满足所有导入。我同意ChrisO,你应该回去查看文档。这里有很多事情似乎过于复杂。为什么那里有new EventAggregator()? MEF应该为您导入该依赖项。为什么所有人都在搞乱容器并获得出口?看来你正在做很多应该由MEF和Prism处理的工作。