Prism事件聚合器不能从单独的模块工作 [英] Prism event aggregator not working from separate module

查看:182
本文介绍了Prism事件聚合器不能从单独的模块工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对棱镜事件聚合器有麻烦。如果我订阅并在同一个模块中发布一个事件,它可以正常工作。像这样 -

  public class InfrastructureModule:IModule 
{
private IEventAggregator eventAggregator;

public InfrastructureModule(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
eventAggregator.GetEvent< TestEvent>()。订阅(TestSub);
}

public void Initialize()
{
eventAggregator.GetEvent< TestEvent>()。Publish(Infrastructure module);
}

private void TestSub(string s)
{
MessageBox.Show(s);
}
}

但是,如果我订阅另一个模块中的事件,发生在eventAggregator.GetEvent()。Publish()被调用时 -

  public class OtherModule:IModule 
{
private IEventAggregator eventAggregator;

public OtherModule(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}

public void Initialize()
{
eventAggregator.GetEvent< TestEvent>()。Publish(Other module);
}
}

基础架构模块首先注册,所以问题不是该OtherModule在有订阅者之前发布一个事件。任何想法出了什么问题?



编辑:这里是我注册模块的地方

 code> class Bootstrapper:UnityBootstrapper 
{
protected override DependencyObject CreateShell()
{
return new Shell();
}

protected override void InitializeShell()
{
base.InitializeShell();

App.Current.MainWindow =(Window)this.Shell;
App.Current.MainWindow.Show();
}

protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();

ModuleCatalog moduleCatalog =(ModuleCatalog)this.ModuleCatalog;

//基础架构模块
moduleCatalog.AddModule(typeof(Infrastructure.InfrastructureModule));


moduleCatalog.AddModule(typeof(Other.OtherModule));
}
}


解决方案

在OP的注释上,对象被实例化,然后被破坏。

这使得 Publish(OtherModule); 代码什么都不做,因为监听器被销毁。



现在确实,如果您将 KeepSubscriberReferenceAlive 设置为 true

它将因为您的EventAggregator将保留对订户对象的引用( InfrastructureModule )。

这不是理想的,基本上你从使用一个弱的事件模式,你不会冒着内存泄漏的风险,
不得不处理对象的生命周期,从而像内存泄漏一样冒着内存泄漏事件。



不要误会我,我不是说绝对不应该使用KeepSubscriberReferenceAlive,而应该只在少数情况下使用。 >

据说您的测试用例是一个奇怪的情况:Bootstrapper将在您定义的每个模块上调用Initialize,然后shell不持有这些模块。因为没有人持有这些模块,它们被破坏。



Initialize 的正常使用是注入正在初始化为 Shell (或任何其他UserControl)的模块,这是有道理的:您不想初始化不会使用的内容。


I am having trouble with the prism event aggregator. If I subscribe to, and publish an event in the same module it works fine. Like this -

public class InfrastructureModule : IModule
{
    private IEventAggregator eventAggregator;

    public InfrastructureModule(IEventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
        eventAggregator.GetEvent<TestEvent>().Subscribe(TestSub);
    }

    public void Initialize()
    {
        eventAggregator.GetEvent<TestEvent>().Publish("Infrastructure module");
    }

    private void TestSub(string s)
    {
        MessageBox.Show(s);
    }
}

However if I subscribe to the event in another module nothing happens when eventAggregator.GetEvent().Publish() is called -

public class OtherModule : IModule
{
    private IEventAggregator eventAggregator;

    public OtherModule (IEventAggregator eventAggregator)
    {
        this.eventAggregator = eventAggregator;
    }

    public void Initialize()
    {
        eventAggregator.GetEvent<TestEvent>().Publish("Other module");
    }
}

The Infrastructure module is registered first so the problem is not that OtherModule is publishing an event before there is a subscriber. Any ideas whats going wrong?

Edit: Here is where I am registering the modules

class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return new Shell();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        App.Current.MainWindow = (Window)this.Shell;
        App.Current.MainWindow.Show();
    }

    protected override void ConfigureModuleCatalog()
    {
        base.ConfigureModuleCatalog();

        ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;

        // Infrastructure module
        moduleCatalog.AddModule(typeof(Infrastructure.InfrastructureModule));


        moduleCatalog.AddModule(typeof(Other.OtherModule));
    }
}

解决方案

Based on the comments of the OP, the objects are instantiated then destroyed right after.
This makes the Publish("OtherModule"); code do nothing, because the listener was destroyed.

Now indeed, if you set KeepSubscriberReferenceAlive to true,
it will work because your EventAggregator will keep a reference to the subscriber object (InfrastructureModule).
That is not ideal, basically you went from using a Weak Event Pattern where you don't risk memory leaks,
to having to handle objects lifetime and thus risk memory leaks just like a regular .NET event.

Don't get me wrong, I'm not saying you absolutely shouldn't use KeepSubscriberReferenceAlive, but it should only be used on rare occasions.

That being said, your test case is an odd scenario: the Bootstrapper will call Initialize on every Module you define, and then your shell does not hold those modules. Since nobody holds those Modules, they're destroyed.

The "normal" usage for Initialize, is to inject the module that is being initialized into the Shell (or any other UserControl), and it makes sense: you don't want to initialize something you will not use.

这篇关于Prism事件聚合器不能从单独的模块工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆