Shell imports twice - can't figure out how to properly code Bootstrapper

Topics: Prism v4 - WPF 4
Jun 29, 2012 at 5:55 PM
Edited Jun 29, 2012 at 5:56 PM

Here is my Bootstrapper and I'm not sure what happening..

public class Bootstrapper : MefBootstrapper
    {
        protected override void ConfigureAggregateCatalog()
        {
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        }
        protected override void InitializeShell()
        {
            base.InitializeShell();
            Application.Current.MainWindow = (Shell)this.Shell;
            Application.Current.MainWindow.Show();
        }
        protected override DependencyObject CreateShell()
        {
            return this.Container.GetExportedValue<Shell>();
        }
    }

I see that my VM an View exported twice for Shell. Once in CreateShell and second time on base.InitializeShell();

 

CreateShell is required. If I remove base.InitializeShell then my Regions is not loaded. How do I fix this? 


Developer
Jun 29, 2012 at 8:33 PM

Hi,

This seems to be related to a known issue in Modularity Quickstart with MEF, where the Shell is composed two times; first in the CreateShell method and then in the InitializeShell method of the MefBootstrapper base:

We tried changing the InitializeShell method in several Quickstarts to remove the invocation to its base method, and they worked without any problems.

However, if for some reason removing the call to the base InitializeShell method is causing an undesired behavior in your application, another possible approach is to create the Shell without using the container in the CreateShell method. For example, your Shell could have a parameter-less constructor, turning all the parameters (if any) into properties or members with importing attributes and implementing the IPartImportsSatisfiedNotification so that your Shell is notified when it is composed and all the values are available. Therefore, your CreateShell method could look like this:

protected override DependencyObject CreateShell()
{
    return new Shell();
}
And your Shell would only be composed once when the base InitializeShell method is invoked.

I hope you find this useful,

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

Jun 29, 2012 at 8:50 PM

Damian,

Your suggestion worked, thank you. In my case removing call to base.InitializeShell() didn't work because RegionManager didn't have any regions loaded and I use region navigation to initially populate Shell.

Nov 29, 2014 at 9:37 AM
Actually following line is unnecessary
Application.Current.MainWindow = (Shell)this.Shell;

because already done by the ServiceLocater (after calling CreateShell method). Same for many other examples in PRISM family (quickstarts, Unity, MEF etc)
  • ok its small beer but IMHO should be fixed to reduce fluff