C# 带有EventAggregator和ViewModel的RegisterType

C# 带有EventAggregator和ViewModel的RegisterType,c#,wpf,mvvm,unity-container,eventaggregator,C#,Wpf,Mvvm,Unity Container,Eventaggregator,我不明白如何注册IEventAggregator实例,以便将其注入ViewModel 例如: 我定义我的MainViewModel: ... private IEventAggregator _eventAggregator; public MainViewModel(IEventAggregator eventAggregator) { _eventAggregator = eventAggregator; ... } ... 然后,我需要以某种方式注册一个实现IEvent

我不明白如何注册
IEventAggregator
实例,以便将其注入
ViewModel

例如:

我定义我的
MainViewModel

...
private IEventAggregator _eventAggregator;

public MainViewModel(IEventAggregator eventAggregator) {
    _eventAggregator = eventAggregator;
    ...
}
...
然后,我需要以某种方式注册一个实现
IEventAggregator
的类,我想将该类注入我的
ViewModel

在我的
ModuleInit
类中,我会有如下内容:

...
private IUnityContainer _container;

public ModuleInit(IUnityContainer _container) {
   _container = container;
}
...
public void Initialize() {
   container.RegisterType<IEventAggregator, ___(something)___>();
   ...
}
。。。
专用IUnityContainer\u容器;
公共模块单元(IUnityContainer\u容器){
_容器=容器;
}
...
公共无效初始化(){
container.RegisterType();
...
}
在我的
MainViewModel
类中,我还可以实现
\u eventAggregator=ServiceLocator,Current.GetInstance(),但我在概念上并不真正理解我在做什么。这个程序很有效


我很想了解
ServiceLocator
实际上在做什么,以及我应该做什么来适当地向容器注册类型。我没有定义一个实现
IEventAggregator
的类,那么
ServiceLocator
在哪里获取实例呢?然后我需要注册什么,这样当我解析某个对象时,比如我的
ViewModel
,它将创建一个新的
EventAggregator
实例?

Microsoft Prism framework拥有
Microsoft.Practices.Prism.Events.EventAggregator
类,该类实现了
IEventAggregator
。假设您已经通过扩展
UnityBootstrapper
实现了引导程序,我记得,它已经将
IEventAggregator
注册到
EventAggregator
类,因此您无需再这样做。 使用UnityContainer解析
IEventAggregator
将为您提供
EventAggregator
Singleton实例


您的ServiceLocator无法在内部调用容器。请解析以获取EventAggregator实例,因此它对您有效。

EventAggregator:

Prism库有一个默认的
EventAggregator
,您可以使用它。 如果您使用Prism<5.0,它位于Microsoft.Practices.Prism.Events中;如果您使用Prism>=5.0,它位于Microsoft.Practices.Prism.PubSubEvents中

此外,如果您使用的是来自
UnityExtensions
UnityBootstrapper
,我怀疑您也在使用模块,那么prism中的所有内置服务(包括
EventAggregator
)都将为您注册:

class MyBootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        // the base.ConfigureContainer setup all build in prism services
        base.ConfigureContainer();

        //register your own stuff
    }
}
服务定位器:

ServiceLocator
只是一个静态包装器,它与
IUnityContainer
的当前实例联系以获得解析。您应该永远不要使用
ServiceLocator
获取解析,除非无法以其他方式获取解析(例如在静态构造函数中)。这种模式被称为服务定位器模式,通常不受欢迎

UnityContainer:

容器的任务是创建注册到特定接口的任何类的实例,监视它们的生存期,并在指定的情况下重用实例。 因此,当您注册时:

container.RegisterType<IEventAggregator, EventAggregator>();
这指示容器在每次请求时重用同一实例。 使用
RegisterType
时,默认的生存期管理器是
TransientLifetimeManager
,它将指示容器每次创建一个新实例

注意:如果您在某个时候使用了
注册表状态
,那么请注意默认的lifetimeManager是
容器控制的lifetimeManager
,而不是瞬态

进一步阅读:

我建议您仔细阅读依赖注入和控制反转,这正是您试图做的。也可能是棱镜工作原理的教程


干杯

感谢您的详细回复。既然引导程序的
Run()
方法实现了
UnityBootstrapper
注册了必要的服务,我不应该只调用
container.Resolve()
,它将注入
EventAggregator
的实例吗?目前,我得到的
对象引用未设置为对象的实例。
错误。这就是我的困惑所在。是的,这就是应该发生的事情。当您调用
Resolve()
时,可能是在容器设置之前?尝试发布异常的堆栈跟踪。在初始化模块时调用
public void Initialize(){}
此时,应该设置EventAggregator。。尝试
var聚合器=_container.Resolve()
如果有效,那么就不是聚合器来澄清,目前,我正在使用
公共void Initialize(IMainViewModel viewModel):this(){this.DataContext=viewModel}
设置
数据上下文
,然后在
模块
实例化期间注册/解析(即
\u container.RegisterType()u container.Resolve();
... , EventAggreagator>(new ContainerControlledLifetimeManager());