views:

877

answers:

2

Hi,

I have created a project using the PRISM framework. I have a few modules that I can register and display in the shell and this works fine. What I need to do is dynamically display and hide the modules when a particular event is received from the event aggregator.

I fire off a DisplayModule event that should be received and hide an existing module and show a new one, but my question is where is the place I should receive this event and display the module? the shell? if so, how would I do this as the shell is the top level and doesn't seem to inherit the required Unity methods.

I also thought I could have a seperate module that listened for the DisplayModule event and used the region manager to hide the previous module and show the new one. This would need to reference all other modules to be able to resolve their type though, is this bad practice?

Hope that makes sense.

Thankyou for your time

+3  A: 

You can't unload an entire module, though. You can dynamically load one, but not unload one. For more information read Loading Modules on Demand in the following article: http://msdn.microsoft.com/en-us/library/dd458911.aspx

Assumption: I'm going to start off with the assumption that when you say you want to unload a module, you really just want all of its views to be removed from your application.

First off, let's talk about how your modules work and how they show their content on your shell.

Your shell will have one or more Regions that your modules can then register views with when they are initialized.

public MyFirstModule : IModule
{
     IRegionManager _mgr;
     public MyFirstModule(IRegionManager mgr)
     {
          _mgr = mgr;
     }

     public void Initialize()
     {
          _mgr.RegisterViewWithRegion("MainRegion", typeof(MyView));
     }

}

What you can do, though, is change your module initialization to track views that have been registered with this module and unload them when appropriate.

public MyFirstModule : IModule
{
     IRegionManager _mgr;
     IEventAggregator _agg;
     IUnityContainer _container;
     public MyFirstModule(IRegionManager mgr, 
                          IEventAggregator agg, 
                          IUnityContainer container)
     {
          _mgr = mgr;
          _agg = agg;
          _container = container;
     }

     List<object> Views = new List<object>();
     public void Initialize()
     {
          _mgr.RegisterViewWithRegion("MainRegion", () =
          {
               MyView view = _container.Resolve<MyView>();

               //Track this view so I can remove it if needed
               Views.Add(view);
               return view;
          });

          _agg.GetEvent<UnloadModuleRequest>.Subscribe(RemoveViews,                
                                                       ThreadOptions.UIThread);
     }

     private void RemoveViews(string moduleToUnload)
     {
          //If this is true, that means the Shell is asking
          //me to unload, so I will remove any views I've
          //registered from any regions they were registered to
          if(moduleToUnload == "MyFirstModule")
          {
               foreach(object view in Views)
               {
                    _mgr.Regions["MainRegion"].Remove(view);
               }
          }

     }

}

That way your Shell can publish an event called UnloadModuleRequest (of type CompositePresentationEvent<string>) and have any module listening unload any views it has registered.

I hope this is close to what you are wanting.

Anderson Imes
+2  A: 

Hi

The following threads deal with similar situations and explain possible ways of achieving your goals:

Please let me know if this helps.

Damian Schenkelman http://blogs.southworks.net/dschenkelman

dschenkelman
This doesn't really mention anything about unloading a module.
Anderson Imes
That first thread is pretty good, though. Some of the same things mentioned in there will likely come up when "reloading" the module. Maybe this discussion will talk suiva out of doing what he/she is trying to do though... it sounds like the OP has a slight misunderstanding of what a module is and that thread irons it out a lot. Thanks for posting it.
Anderson Imes