Prism 4 + Mef + public partial class App = Bag?

Topics: Prism v4 - WPF 4
Oct 9, 2011 at 11:59 AM

Hi.

I'm trying to implement the interface IPartImportsSatisfiedNotification but unfortunately it does not work. This bug I have only the prism. I can't understand why this is happening.

public partial class App : Application, IPartImportsSatisfiedNotification
{
    [Import]
    public IPlugin plugin { get; set; }

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

    public void OnImportsSatisfied() // This code is not called
    {
        var x = plugin;
    }
}

Test Application

Developer
Oct 11, 2011 at 6:59 PM

Hi,

The Application class "Encapsulates a Windows Presentation Foundation (WPF) application.", and it is created implicitly when you start a WPF application, in case you define it using markup, or markup and code-behind (which is the case when using the Silverlight Application template in Visual Studio 2010).

Your instance of the App class (which inherits from Application) is treated as a singleton, holded by the Application.Current static property, and this is done, as previously mentioned, in an implicit manner, before the creation of the MEF container (because it's the first thing done when you start your application).

Therefore, based on my understanding, the container won't instantiate this class by default, and thus it won't be able to satisfy imports in it. Even if you decorate your App class with the Export attribute, the instance that is implicitly generated on application start-up won't be composed by the container.

So, in order to workaround this issue you're experiencing, there are multiple alternatives:

  • You could compose the already existing instance of the App class into the container (which in Silverlight is done through the CompositionInitializer.SatisfyImports method). However, take into account that in WPF there is no CompositionInitializer class. You might find this blog post by Reed Copsey Jr. useful, as it proposes a way to have something similar in WPF.
  • You could manage yourself the creation of the App class. To this regard, you should create and initialize the MEF container before creating the App class, which is not the default scenario in Prism, so you might have to make some modifications to the Prism Library (especially in the bootstrapper class).
  • You could obtain a reference to the component you need through the ServiceLocator, which does not need that your class is composed by the bootstrapper in order to use it. You can find more information about the service locator in the following link of the Prism documentation.
  • In case it's possible, you could place your import on other components (for example, a service or controller instantiated by the Bootstrapper, or in the Shell), which is in my opinion a better design decision.

I hope you find this helpful.

Agustin Adami
http://blogs.southworks.net/aadami