Агрегатор событий Prism не работает из отдельного модуля - PullRequest
6 голосов
/ 28 декабря 2011

У меня проблемы с агрегатором событий призмы. Если я подписываюсь и публикую событие в том же модуле, он работает нормально. Как это -

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);
    }
}

Однако, если я подписываюсь на событие в другом модуле, ничего не происходит, когда вызывается 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 публикует событие до того, как появится подписчик. Есть идеи, что не так?

Редактировать: Здесь я регистрирую модули

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));
    }
}

1 Ответ

8 голосов
/ 28 декабря 2011

Основываясь на комментариях ОП, объекты создаются и уничтожаются сразу после.
Это заставляет код Publish("OtherModule"); ничего не делать, потому что слушатель был уничтожен.

Теперь действительно, если вы установите KeepSubscriberReferenceAlive на true,
будет работать, потому что ваш EventAggregator сохранитссылка на объект подписчика (InfrastructureModule).
Это не идеально, в основном вы перешли от использования шаблона слабых событий, где вы не рискуете утечки памяти,
к необходимости обрабатывать время жизни объектов и, таким образом, рисковать утечки памяти, как обычное событие .NET.

Не поймите меня неправильно, я не говорю, что вам абсолютно не следует использовать KeepSubscriberReferenceAlive, но его следует использовать только в редких случаях.

При этом ваш тестовый пример нечетныйСценарий: Bootstrapper будет вызывать Initialize для каждого модуля, который вы определяете, и тогда ваша оболочка не будет содержать эти модули.Поскольку никто не держит эти Модули, они уничтожаются.

"Нормальное" использование для Initialize - это внедрение модуля, который инициализируется, в Shell (или любой другой UserControl), и этоимеет смысл: вы не хотите инициализировать то, что не будете использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...