Почему мой метод подписки не вызывается при использовании Prism EventAggregator? - PullRequest
2 голосов
/ 23 июня 2019

Я изучаю Призму. Уже несколько часов я сталкиваюсь с проблемой, при подписке на событие метод подписки не вызывается. Я использую Prism и Autofac .

В приведенном ниже упрощенном примере в MainViewModel Publish("dupa"); вызывается событие ctor. И по нажатию кнопки UpdateWindow открывается. В бэкэнде окна создается экземпляр UpdateViewModel .

Внутри обновление VM ctor запущено, но после Subscribe(UpdateName); UpdateName не выполняется по какой-то причине, которую я не понимаю.

Полный код:

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

После расследования я заметил, что при подписке на подобные события работает нормально:

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

При подписке с использованием введенного eventAggregator не работает:

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

И EventAggregator зарегистрирован Autofac следующим образом:

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

Я не понимаю, почему эта зависимость не работает?

1 Ответ

2 голосов
/ 24 июня 2019

Я не понимаю, почему эта зависимость не работает?

Поскольку вы создаете новый EventAggregator для UpdateViewModel.

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

Этовыглядит так, как будто для UpdateWindow создан новый контейнер, и новый контейнер будет иметь новый, то есть другой, EventAggregator.Разумеется, эти двое не будут отправлять события друг другу.

Поэтому решение состоит в том, чтобы использовать один единственный контейнер для разрешения всех ваших вещей.Это то, что происходит, когда вы используете статический Utility.Вам следует избегать использования сервис-локатора, подобного этому.Взгляните на ViewModelLocator, который позволяет действительно легко создавать модели видов для данного вида, например, или передать контейнер в UpdateWindow, когда он создается (хотя и несколько уродливо).

...