1

I am learning Prism. Few hours already I am facing a problem, when subscribing to the event, the subscription method is not called. I am using Prism and Autofac.

In the simplified example below, in MainViewModel Publish("dupa"); event is called in the ctor. And on button click UpdateWindow is opened. In backend of the window is created instance of UpdateViewModel.

Inside of update VM ctor is ran, but after Subscribe(UpdateName); the UpdateName is not executed, because of some reason that I do not understand.

Complete code:

public class MainViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;
        public MainViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism

            _eventAggregator.GetEvent<UpdateNameEvent>().Publish("dupa");

            OnOpenCommand = new DelegateCommand(OnOpenWin);
        }

        public void OnOpenWin(object obj)
        {
            UpdateWindow win = new UpdateWindow();
            win.Show();
        }

        public ICommand OnOpenCommand { get; private set; }
    }


public class UpdateViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;

        public UpdateViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism
            _eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);
        }

        private void UpdateName(string name)
        {
            this.Name = name; //is not called at all
        }

        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }


public partial class UpdateWindow : Window
    {
        public UpdateWindow()
        {
            var bootStrapper = new BootStrapper();
            var container = bootStrapper.BootStrap();
            UpdateViewModel vm = container.Resolve<UpdateViewModel>();
            InitializeComponent();
            DataContext = vm;
        }
    }

UPDATE

After investigating, I notied, that when subscribing to the events like this, it works fine:

Utility.EventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

When subscribing with used injected eventAggregator, it does not work:

_eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

And EventAggregator is registered by Autofac as follows:

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

I do not understand why this dependency does not work?

bakunet
  • 197
  • 1
  • 12

1 Answers1

1

I do not understand why this dependency does not work?

Because you create a new EventAggregator for the UpdateViewModel.

var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
UpdateViewModel vm = container.Resolve<UpdateViewModel>();

This looks as if a new container is created for the UpdateWindow, and the new container will have a new - that is, a different - EventAggregator. Those two will not send events to each other, of course.

So the solution is to use one single container to resolve all your stuff. This is what happens when you use the static Utility. You should avoid using a service-locator like this. Have a look at the ViewModelLocator, which makes it really easy to create the view models for a given view, for example, or pass the container to the UpdateWindow when it is created (somewhat ugly, too, though).

Haukinger
  • 10,420
  • 2
  • 15
  • 28
  • It sounds interesting. As I am using Prism, Ill try to use its automatic VM locator... – bakunet Jun 24 '19 at 08:16
  • Based on this solution: https://stackoverflow.com/questions/25366291/how-to-handle-dependency-injection-in-a-wpf-mvvm-application I created VM locator and resolved EventAggregator as a singletone and it worked. Thank you – bakunet Jun 24 '19 at 12:23