I am having trouble with the prism event aggregator. If I subscribe to, and publish an event in the same module it works fine. Like this -
public class InfrastructureModule : IModule
{
private IEventAggregator eventAggregator;
public InfrastructureModule(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
eventAggregator.GetEvent<TestEvent>().Subscribe(TestSub);
}
public void Initialize()
{
eventAggregator.GetEvent<TestEvent>().Publish("Infrastructure module");
}
private void TestSub(string s)
{
MessageBox.Show(s);
}
}
However if I subscribe to the event in another module nothing happens when eventAggregator.GetEvent().Publish() is called -
public class OtherModule : IModule
{
private IEventAggregator eventAggregator;
public OtherModule (IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
public void Initialize()
{
eventAggregator.GetEvent<TestEvent>().Publish("Other module");
}
}
The Infrastructure module is registered first so the problem is not that OtherModule is publishing an event before there is a subscriber. Any ideas whats going wrong?
Edit: Here is where I am registering the modules
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return new Shell();
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
// Infrastructure module
moduleCatalog.AddModule(typeof(Infrastructure.InfrastructureModule));
moduleCatalog.AddModule(typeof(Other.OtherModule));
}
}
Based on the comments of the OP, the objects are instantiated then destroyed right after.
This makes the Publish("OtherModule");
code do nothing, because the listener was destroyed.
Now indeed, if you set KeepSubscriberReferenceAlive
to true
,
it will work because your EventAggregator will keep a reference to the subscriber object (InfrastructureModule
).
That is not ideal, basically you went from using a Weak Event Pattern where you don't risk memory leaks,
to having to handle objects lifetime and thus risk memory leaks just like a regular .NET event.
Don't get me wrong, I'm not saying you absolutely shouldn't use KeepSubscriberReferenceAlive, but it should only be used on rare occasions.
That being said, your test case is an odd scenario: the Bootstrapper will call Initialize on every Module you define, and then your shell does not hold those modules. Since nobody holds those Modules, they're destroyed.
The "normal" usage for Initialize
, is to inject the module that is being initialized into the Shell
(or any other UserControl), and it makes sense: you don't want to initialize something you will not use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With