使用 Unity 属性 依赖注入和 EventAggregator

Use Unity Property Dependency Injection with EventAggregator

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

我有 BaseViewModel,所有 ViewModel classes 都将从

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

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

这里是 ViewModel 之一的示例 class

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 设置依赖关系 属性,这是事件的逻辑顺序,但它不适合我。 TablesViewModel 的构造函数给出空引用异常,因为 EventAggregator 属性 仍然为空。

我不想使用构造函数依赖注入,这将迫使我为所有 ViewModel classes 创建大量非默认构造函数。 同时,我需要在构造函数中订阅 EventAggregator(因为没有其他好的地方可以这样做,如果有请告诉我)。

我该如何解决这个问题

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

如果您需要在构造函数中访问事件聚合器,您应该使用构造函数依赖注入或从一些静态 属性.

中检索事件聚合器

I do not want to use the constructor dependency injection, this will force me to create a lot of non-default constructor for all the ViewModel classes.

想要 类 具有依赖性的非默认构造函数。这就是依赖注入的全部内容:类型通过它们的构造函数参数告诉用户他必须给他们什么才能操作。

有很多方法可以使用非默认构造函数创建视图模型,例如Prism 的 ViewModelLocator 或 Unity 的自动工厂。除非绝对必要,否则您不想求助于 ServiceLocator,但从技术上讲,邪恶的人可以做这样的事情:

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