views:

43

answers:

2

Righty oh now I believe ive set this application up right but correct me if im wrong, for simple sake i have in my bootstrapper 3 modules loaded, one is a navigation module, and two others the views.

Independently in code if i load the modules and in the initialize method add them to a region that all works fine, however ofcourse id like some more control.

Now in the navigation view model i have an event aggregator which publishes an event (class that inherits from EventArgs if thats important) the other two modules have subscribed to this event but neither recieve it,

/// <summary>
    /// Carries the out menu item selection methods.
    /// </summary>
    /// <param name="e">The <see cref="TMBL.Web.TMBLCore.Controls.Assets.NavigationViewSelectionEventArgs"/> instance containing the event data.</param>
    public void CarryOutMenuItemSelectionMethods(NavigationViewSelectionEventArgs e)
    {
        _eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Publish(e);
    }

in navigation ViewModel,and then subscribed to in news module

_eventAggregator.GetEvent<NavigationMenuItemSelectedEvent>().Subscribe(NavigationMenuReturnedEvent,
                                                                               ThreadOption.UIThread);

Seemed simple enough, i can subscribe to this event in my navigation module and it picks it up, it just wont go outside the module, what does one need to do to achieve this?

Also the event aggregator is pushed in through dependency injection to the modules constructor, then stored there and passed onthrough constructors to the viewsand view models (views first approach by the way). Whilst im here I dont know if this is the cause of the problem or not but is it bad to have the module store an instance of event aggregator and pass it on this way eg

_displayNewsView = new DisplayNewsView(new DisplayNewsViewModel(_eventAggregator));

Or should the event aggregator get to the viewmodels a different way?

Thanks for you time

+1  A: 

You are injecting the event aggregator correctly but there are a couple of things you need to check.

1) Is the event aggregator instance global to the application and not created by each module. The same instance must be used across modules. This should get created within the application bootstrapper and passed to each module.

2) Is the NavigationMenuItemSelectionEvent defined in a common assembly that is shared across modules? If this the case (as I would expect) then make sure the same assembly is used across modules. You can check this when you load the application using the debugger and view the loaded assemblies using the Modules window (Debug > Windows menu). The assembly should only be listed once.

If you see the common assembly loaded multiple times then it could be down to that you are loading modules from different directories and the common assembly is NOT signed. .Net will treat these as separate and therefore the NavigationMenuItemSelectionEvent type will not match.

Either have the assembly signed ensuring all modules using the same instance of the assembly or ensure that all modules get loaded from the same directory (including the application if it too uses the common assembly).

aqwert
A: 

Okay stack overflow lost my nice big reply. So I need an event aggregator instance in my bootstrapper as all modules need to use the same service, this makes sense to me. However I thought dependency injection would take care of this, I need an instance of the event aggregator in my bootstrapper? my issue with this is two fold firstly how to instaniate it

 protected override DependencyObject CreateShell()
    {
        _eventAggregator = new EventAggregator();
        var shell = Container.Resolve<Shell>();
        Application.Current.RootVisual = shell;
        return shell;
    }

Would that work? Secondly how do I pass this instance to my modules in the boot strapper as at the moment they are created when added to the module catalogue i believe

 protected override IModuleCatalog GetModuleCatalog()
    {
        var catalog = new ModuleCatalog();
        catalog.AddModule(typeof(TMBLCoreModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(NewsModule), InitializationMode.WhenAvailable);
        catalog.AddModule(typeof(UserModule), InitializationMode.WhenAvailable);
        return catalog;
    }

How would I then pass the event aggregator into each module. I've had a quick google but havent been able to find this information yet, sorry for my ignorance

Lee
Okay i have managed to finally track it down after a few failed attempts, when i register the instance of the event aggregator i had to tell it treat it as a singleton Container.RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager()); http://blogs.msdn.com/b/francischeung/archive/2008/06/02/decoupled-communication-with-prism-event-aggregation.aspx
Lee
Also sorry stackoverflow signed me into a temp account rather than my own and i cant work out how to get back on it to accept your answer, appologies, thank you very much
Lee
email [email protected] and they should be able to merge the 2 accounts.
aqwert