Search code examples
c#dependency-injectionprismautofaceventaggregator

How do I register an EventAggregator as a singleton in an MVVM app?


Building my first MVVM application, and it's introducing some really powerful concepts, but at the same time it's a lot to learn at once. The issue I'm having right now is that event subscribers don't seem to be receiving the events when I publish them from another ViewModel.

I think I need to new up an EventAggregator in App.xaml.cs or in my BootStrapper class and then inject that instance into each ViewModel that needs to reference it. I think what's happening is that a new IEventAggregator is being created for each view model and I'm pubbing/subbing to different instances. Not sure if my disconnect is with the EventAggregator Pattern/Prism or DI/Autofac here.

Should I do something like this:

public partial class App : Application
{
    //Add this...
    IEventAggregator eventAggregator = new EventAggregator();

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        //... and pass in here somehow?
        var window = new BootStrapper()
            .Bootstrap()
            .Resolve<AView>();

        window.Show();
    }
}

Or like this:

public class BootStrapper
{
    //Add this...
    IEventAggregator eventAggregator = new EventAggregator();

    public IContainer Bootstrap()
    {
        var builder = new ContainerBuilder();


        builder.RegisterType<AView>()
            .AsSelf();
        builder.RegisterType<AViewModel>()
            .AsSelf();

        builder.RegisterType<OtherViewModel>()
            .As<IOtherViewModel>();
        builder.RegisterType<ADataProvider>()
            .As<IADataProvider>();
        builder.RegisterType<ADataService>()
            .As<IDataService<Account>>();

        //What I'm doing now
        builder.RegisterType<EventAggregator>()
            .As<IEventAggregator>();

        //...and register instance here?

        builder.RegisterType<AccountSelectedEvent>()
            .AsSelf();

        return builder.Build();
    }

Advice, references, or nudges in the right direction equally appreciated. Thanks!


Solution

  • I figured it out, and it was... embarrassingly simple. In my BootStrapper

    Before

    Type was registering fine, but was injecting a new instance each time an instance was requested, and so I was pubbing to one, subbing to another.

        builder.RegisterType<EventAggregator>()
            .As<IEventAggregator>();
    

    After

    Oh my god.

        builder.RegisterType<EventAggregator>()
            .As<IEventAggregator>()
            .SingleInstance;