Get Events Firing During CreateShell()

Topics: Prism v4 - Silverlight 4, Prism v4 - WPF 4
Apr 27, 2012 at 4:06 PM

I have a startup sequencing problem I'd like to solve in a better way.

What I want to be able to do is have my initial UI (after the shell) be injected via event subscription.  But it seems I can't subscribe to any events until after the CreateShell() method completes because other modules aren't initialized yet.

How I've been doing it so far is similar to this:

  • Bootstrapper runs
  • CreateShell() method runs, shows the Shell UI
  • Inject a predetermined view into a region in the Shell
  • CreateShell() method ends
  • Then I can either raise an event in the view's code behind window_loaded event, or wait for user input (like on a login screen)

To give you a better scenario to consider, I have 2 possible login methods:  Login screen, or Single Sign on

Using the Login screen is simple and is done using the listed approach above.  When the user pressed the Login button I can process the credentials and raise an event to inject other views.  No problem.

Now, if I want to use Single Sign On, this means when the CreateShell method runs, I want my Authentication module to load, process credentials then raise an event saying the user is authenticated.  Then, whatever module I want can decide what UI to inject for the user via event subscription.

The only thing I can't do in that scenario is subscribe to events in time.  Modules aren't loaded in time durng the CreateShell() method where everything happens.

The process seems to go like this:

  • Bootstrapper runs
  • CreateShell() method runs, shows the Shell UI
  • Inject user authentication view (hidden) which allows me to authenticate a user in the background
  • Raise an event the user is authenticated
  • CreateShell() method ends
  • Now modules init and I can subscribe to events, but it's too late, the event has already fired

Does that make sense?

Perhaps another way to say my question is:  How do I raise an event that the bootstrap process is complete so I can inject my initial UI?  Or more accurately, how can I subscribe to the event so it will be processed after the bootstapper runs?

Thanks in advance, any ideas are welcome.

Developer
Apr 27, 2012 at 8:03 PM
Edited Apr 27, 2012 at 8:07 PM

Hi,

In this scenario, I believe that the best approach could be to authenticate the user after the "start-up" process is finished and the required modules are loaded. If you want to know when the Run method of your Bootstrapper has finished, a possible approach could be to execute the logic to authenticate the user in the App class after the invocation of the Run method:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    MyBootstrapper bootstrapper = new MyBootstrapper();
    bootstrapper.Run();
    // Invoke method to authenticate user
}

If instead, you want to do this through an event, as a possible approach you can define your own Run method in your Bootstrapper so that the original base Run method is called and then an event is raised:

public new void Run()
{
    base.Run();
    // Raise an event in your bootstrapper
}

However, take into account that, in some scenarios, even if the "bootstrapper process" is finished it does not mean that the required modules would be available. If you want to make sure that the required modules are loaded you can subscribe to the LoadModuleCompleted event of the ModuleManager and wait until all the required modules are loaded.

Also, I believe that another possible approach could be to use a Shared Service instead of using events. For example, when the user is authenticated you can save this state in a service and then, when the corresponding modules are initialized, each module itself could retrieve the service, check if the user has been authenticated and perform its the corresponding tasks.

I hope you find this useful,

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