将Unity属性依赖注入与EventAggregator一起使用

时间:2018-11-09 15:02:45

标签: wpf dependency-injection unity-container prism eventaggregator

我有带有Prism 7.1,Unity DI 5.8.11和.NET Framework 4.7的WPF项目

我有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的构造函数,然后由Unity DI设置Dependency属性,这是一个逻辑顺序事件,但它不适合我。 TablesViewModel的构造方法给出了空引用异常,因为EventAggregator属性仍然为空。

我不想使用构造函数依赖项注入,这将迫使我为所有ViewModel类创建很多非默认构造函数。 同时,我需要在构造函数上订阅EventAggregator(因为请告诉我,没有别的好地方可以这样做了。)

我该如何解决

2 个答案:

答案 0 :(得分:1)

在创建类的实例之前不能设置属性 ,即,在构造函数执行之前将永远不会设置EventAggregator属性。

如果需要访问构造函数中的事件聚合器,则应该使用构造函数依赖项注入,或者从某个静态属性中检索事件聚合器。

答案 1 :(得分:1)

  

我不想使用构造函数依赖项注入,这将迫使我为所有ViewModel类创建很多非默认构造函数。

想要具有依赖项的类的非默认构造函数。这就是依赖注入的全部含义:这些类型通过用户的构造函数参数告诉用户他必须赋予它们进行操作的内容。

有很多方法可以使用非默认构造函数创建视图模型,例如Prism的ViewModelLocator或Unity的自动工厂。除非绝对必要,否则您不希望使用ServiceLocator,但是从技术上讲,邪恶的人可以执行以下操作:

public abstract class BaseViewModel : BindableBase
{
    protected IEventAggregator EventAggregator { get; } = ServiceLocator.Current.GetInstance<IEventAggregator>();
}