使用 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>();
}
我有带 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>();
}