Caliburn Micro EventAggregator подписывает / отменяет подписку на несколько экземпляров одной и той же модели ViewModel

Недавно я обнаружил, что мой метод Handle () вызывается несколько раз после одной публикации ... и обнаружил, что деактивированные и закрытые экземпляры ViewModel на самом деле не утилизируются и продолжают получать сообщения! Я ищу способ либо правильно избавиться от устаревших моделей просмотра, либо просто удалить их из подписки EventAggregator.

Моя оболочка - это

Conductor<T>.Collection.OneActive, IScreenEx where T : class, IScreenEx

Проведенные элементы регистрируются в SimpleContainer следующим образом:

container.PerRequest<ILinkageMovements, LinkageGraphViewModel>();

и активируется так:

    public X SwitchToNamed<X>(String key) where X : T
    {
        var existing = Items.FirstOrDefault(y => y.GetType() == typeof(X) && y.UniqueKey == key);

        if (existing == null)
            existing = Items.FirstOrDefault(x => x.GetType().GetInterfaces().Contains(typeof(X)) && x.UniqueKey == key);

        if (existing != null)
        {
            ChangeActiveItem(existing, false);
            return (X)existing;
        }
        else
        {
            X vm = container.GetInstance<X>();
            vm.UniqueKey = key;
            ActivateItem(vm);
            return vm;
        }
    }

Модель ViewModel устроена так:

    public LinkageGraphViewModel
        (
            Caliburn.Micro.SimpleContainer container,
            Caliburn.Micro.IEventAggregator eventAggregator,
            IDialogManager dialogs,
            IDataService dataService,
            IReferentialData refData
        )
        : base(container, eventAggregator, dialogs, dataService, refData)
    {
        DisplayName = Strings.Movements;
    }

Наконец, конструктор самого базового класса:

    public BaseConductor(SimpleContainer container, IEventAggregator eventAggregator, IDialogManager dialogs)
    {
        this.container = container;
        this.eventAggregator = eventAggregator;
        this.eventAggregator.Subscribe(this);
        this.Dialogs = dialogs;
    }

Пожалуйста помоги.


person alphanoch    schedule 12.06.2015    source источник


Ответы (1)


В интерфейсе IEventAggregator есть Unsubscribe метод.

Ответ на вопрос о том, когда это подходящее время для вызова, зависит от вашей архитектуры - опубликованный вами код не объясняет, когда ваши модели представления больше не нужны - они могут оставаться в элементах навсегда.

Обычно вы подписывались в OnActivate и отписывались в OnDeactivate, однако ваш код подписывается в конструкторе, поэтому я предполагаю, что вы можете захотеть подписаться на неактивные модели, чтобы CanClose мог быть другим кандидатом.

person Alexander Balabin    schedule 12.06.2015