Trying to inject IEventAggregator in Prism Shell not working -- ideas?

Topics: Prism v4 - WPF 4
May 30, 2012 at 3:13 PM

I have my bootstrapper creating an instance of the shell:

 Collapse | Copy Code
        protected override DependencyObject CreateShell ( )
        {
            MainWindow shell = new MainWindow( this.Container.Resolve<IEventAggregator>( ) );
            return shell;
        }
 
        protected override void InitializeShell ( )
        {
            base.InitializeShell( );
 
            App.Current.MainWindow = (Window)this.Shell;
        }

 
and I have my shell consuming the constructor:

 Collapse | Copy Code
        public MainWindow(IEventAggregator aggregator)
        {
            InitializeComponent( );
            this.DataContext = this;
            this.eventAggregator = aggregator;
            eventAggregator.GetEvent<BusyIndicator>( ).Subscribe( SetIndicator, ThreadOption.UIThread );
        }

 
However I found two issues: the framework wanted to call the empty constructor and I kept getting a null exception until I added an empty constructor to the Shell.
Then I added a test in that logic to Assert if the initialized IEventAggregator ended up to be null. No surprise here it was null. So for some reason even though InitializeShell() was called and the window was set, it was recreated by the system (Prism?).
 
Any suggestions on how to inject the event aggregator into the shell of my prism application? Should I not call base.InitializeShell() ??? (though the call to the empty constructor of the shell occurs after the BootStrapper.Run command was executed) I'm building it as a WPF application under the 4.0 framework using Prism 4.1 and Unity 2.0.

Developer
May 30, 2012 at 6:56 PM

Hi,

Based on my understanding, I believe this kind of behavior can occur if the "StartupUri" property is present in the App.xaml file used by your application. Please remember that when creating a Prism application, the aforementioned property should not be present as the Shell window would be manually created in the CreateShell method of your Bootstrapper like you mentioned above. This can also be related to the fact that your application requires your Shell to have a constructor without parameters: when you define a Window in as your "StartupUri" in your App.xaml, the application will search for a constructor without parameters to instantiate the Window.

If this is not the case, it would be helpful if you could provide us with more information or a repro-sample application portraying this problem so that we can help you further with this.

As a side note (which is not related to the aforementioned problem,) regarding how you are injecting the EventAggregator in your Shell, I believe a cleaner approach could be to Create your shell for example like this:

protected override DependencyObject CreateShell ( )
{
    MainWindow shell = this.Container.Resolve<MainWindow>( );
    return shell;
}

The container (in this case Unity) should inject the EventAggregator in your Shell constructor automatically.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

May 30, 2012 at 7:33 PM

Thank you!

 

That was just the thing I was missing.  Quietly buried deep with then header of the app.xaml file!

I originally was doing the Container.Resolve() and was still not seeing the window pop up but was probably because of this issue.