Используйте Внедрение Зависимостей Свойств Unity с EventAggregator - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть проект WPF с Prism 7.1, Unity DI 5.8.11 и .NET framework 4.7

У меня есть BaseViewModel, который все классы ViewModel унаследуют от

public abstract class BaseViewModel : BindableBase
{
    [Dependency]
    protected IEventAggregator EventAggregator { get; set; }

    // just default constructor, no other constructor is needed
}

и вот пример одного из классов ViewModel

public class TablesViewModel : BaseViewModel
{
    public TablesViewModel()
    {
        EventAggregator.GetEvent<OperatorChangedEvent>().Subscribe(.....);
    }
}

и регистр типа как следующий

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterInstance<IEventAggregator>(new EventAggregator());       
}

Теперь произошло следующее: сначала вызывается конструктор BaseViewModel, затем конструктор TablesViewModel, затем свойство Dependency задается Unity DI, это логическая последовательность событий, но это не подходит для меня. конструктор TablesViewModel дает исключительную ситуацию с нулевой ссылкой, поскольку свойство EventAggregator по-прежнему равно нулю.

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

Как я могу решить это

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Я не хочу использовать внедрение зависимости конструктора, это заставит меня создать множество конструкторов не по умолчанию для всех классов ViewModel.

Вы хотите конструкторы не по умолчанию для классов, которые имеют зависимости.Вот что такое внедрение зависимостей: типы сообщают пользователю через параметры конструктора, что он должен дать им для работы.

Существует множество способов создания моделей представлений с конструкторами не по умолчанию, например Prism's ViewModelLocator или автоматические заводы Unity.Вы не хотите прибегать к использованию ServiceLocator, если это не является абсолютно необходимым, но технически злой человек может сделать что-то вроде этого:

public abstract class BaseViewModel : BindableBase
{
    protected IEventAggregator EventAggregator { get; } = ServiceLocator.Current.GetInstance<IEventAggregator>();
}
0 голосов
/ 09 ноября 2018

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

Если вам нужен доступ к агрегатору событий в конструкторе, вы должны либо использовать инжекцию зависимости конструктора, либо извлечь агрегатор событий из некоторого статического свойства.

...