Search code examples
c#wpfprismmef

C# Prism: Instantiate Model before View Instantiation


TL;DR Is there a way to force MEF Prism container to instantiate a class before it's instantiated by View Disovery? i.e before regionManager.RegisterViewWithRegion

I have a business process whereby the user logs in, and then I kick off some database reads. The LoginEvent is registered to the EventAggregator so that other parts of the application can hear it. The problem is that my model MyModel is only instantiated after the dependent views have been registered which of course happens after the login event has passed and gone. I could do this MyModel's constructor but that feels sloppy.

Current Process

1. User logs in
2. LoginEvent is dispatched
2. View switches to MyView
3. MyModel is instantiated and listens for LoginEvent that will never be dispatched

Desired Process

1. MyModel is instantiated and listens for LoginEvent
2. User Logs in
3. LoginEvent is dispatched
4. MyModel hears LoginEvent and kicks of data read.

Any help on this is greatly appreciated.


Solution

  • Instantiate your view ahead of time so that it is available to listen on events. You can use Module concepts as described in prism docs to instantiate your view inside your module Initialize event. This will have following sequence:

    1. App starts up
    2. Module starts up
    3. View instantiated & registered
    4. User Logs in
    5. LoginEvent intercepted
    6. View switches

    Following example gives you some outline (hasn't been tested, but should be structurally valid):

    public class ModuleInit : IModule
    {
      .....
      CompositionContainer container;
      IRegionManager regionManager;
    
      [ImportingConstructor]
      public ModuleInit(CompositionContainer container, IRegionManager regionManager)
      {
          this.container = container;
          this.regionManager = regionManager;
      }
    
      public void Initialize()
      {
         var myView = this.container.GetExportedValue<MyView>();
         regionManager.RegisterViewWithRegion("myregion", () => myView);
      }
    }