Frage

Ich arbeite an der Implementierung einer Ereignisaggregation mit Prisma. Ich habe ein paar Module, und ich möchte, dass jeder von ihnen Ereignisse abonniert, die ihnen sagen, wann sie angefordert werden. Ich begann mit einem abonnierten und Verlag in der Shell ein ganz einfaches Beispiel zu machen. Keine Probleme dort. Jetzt; Wenn ich die Abonnenten in meine Module verschiebe, werden sie nicht ausgelöst. Noch seltsamer ist, dass es tatsächlich ein paar Mal funktioniert hat - alles, was ich in einem Haltepunkt ausstehend war. Es scheint mir also ein Rassenzustand zu sein, aber ich verstehe nicht warum.

Annahme gemacht: Ich muss den iEventaggregator nirgendwo einrichten - z. B. Registrierung im IOC -Container? Dies ist in Prisma eingebaut, so dass ich nur eine Instanz des Ereignisaggregators habe, oder?

Die Frage ist also im Grunde genommen, wie/wo/wann ich meine Abonnenten einrichten soll. Gibt es eine bestimmte Bestellung auf Sachen usw.? In meinem vereinfachten Beispiel habe ich ein Modul myModule. Der Bootstrapper fügt dem Katalog MyModule hinzu - was ihn initialisiert hat:

catalog.AddModule(typeof(MyModule));

MyModule speichert den Aggregator und verwendet diesen, um den MyModulerEquested Event zu abonnieren. Es wird auch eine Menüregistrierung verwendet, um sich im Anwendungsmenü zu registrieren. Die Idee ist, dass das Klicken im Menü schließlich das Ereignis auslösen sollte - MyModule, das angefordert wurde. Dann möchte ich, dass es MyModule verantwortlich ist, herauszufinden, was ich weiter tun soll.

public MyModule(IEventAggregator aggregator, IApplicationMenuRegistry menu)
{
    _applicationMenu = menu;
    _aggregator = aggregator;
}

public void Initialize()
{
    var evnt = _aggregator.GetEvent<MyModuleRequestedEvent>();
    evnt.Subscribe(MyModuleRequested);
    _applicationMenu.RegisterMenuItem("MyModule", evnt);
}

public void MyModuleRequested(bool b)
{
    MessageBox.Show("MyModule requested");
}

Jetzt habe ich einen Knopf in meiner Shell, der diese Veranstaltung veröffentlichen wird. Die Shell erhält den gleichen (?) Ereignis -Aggregator, wenn es gelöst wird.

public Shell(IEventAggregator aggregator)
{
    InitializeComponent();
    var evnt = aggregator.GetEvent<MyModuleRequestedEvent>();
    EventTriggerButton.Click += (s, e) => evnt.Publish(true);
}

Anmerkungen:

  • Haben überprüft, ob die Veranstaltung veröffentlicht wird. Durch das Hinzufügen eines Abonnenten in der Shell wird dieser Abonnent das Ereignis erhalten.
  • Wieder; Der Abonnent in MyModule ist nicht ausgelöst. Es war jedoch seltsamerweise einige Gelegenheiten.
  • Ich benutze die Eingabe nicht zum Ereignis. Es schien, als müssten Sie einen Eingabetyp haben, also habe ich einfach mit einem Dummy-Bool gegangen. Kann ich das loswerden ..?
War es hilfreich?

Lösung

Der Prism -Ereignis -Aggregator verwendet schwache Verweise, um mit den Ereignissen verbunden zu werden. Dies dient dazu, Speicherlecks von Ereignishandlern zu verhindern.

Sobald ein Modulinitializer ausgeführt wurde, wird er entsorgt, sodass Ihr Event -Handler zerstört wird, bevor das Ereignis entlassen wird. Sie können Prisma sagen, dass er den Event -Handler mit einer Überladung von Abonnements beibehalten soll.

evnt.Subscribe(MyModuleRequested, true);

Als Muster neige ich dazu, Ereignis -Abonnenten in eine separate Klasse zu setzen und diese Klasse aus der Module Initialize -Methode aufzurufen. Auf diese Weise bleiben die Ereignisse am Leben, aber getrennt, während das Modul noch zerstört wird.

Andere Tipps

Also habe ich gerade eine Theorie bekommen, aber keine Zeit, sie momentan zu testen. Ich werde es morgen tun.

Frage: Wird das Hinzufügen von Modulen zum Modulecatalog sie am Leben erhalten? Ich nahm an. Daher sollte die MyModule am Leben bleiben - und wird dann ausgelöst, wenn die Veranstaltung veröffentlicht wird.

protected override IModuleCatalog GetModuleCatalog()
{
    var catalog = new ModuleCatalog();
    catalog.AddModule(typeof(MyModule));
    return catalog;
}

Wenn dies das Modul jedoch nicht am Leben hält, ist es offensichtlich, dass es schwierig ist, auf das Ereignis zu reagieren. Das Modul -Objekt stirbt, aber es wird nicht abbestellen - daher werde ich den Abonnenten in der Liste von EventAggregator sehen, aber der Abonnent ist nicht mehr da. Ebenfalls; Ich erwähnte, dass ich tatsächlich gelegentlich funktioniert - was wäre der Fall, wenn der Müllsammler keine Zeit hatte, den Müll herauszunehmen, bevor das Ereignis ausgelöst wird.

Klingt das nach dem Fall? Wenn ja - ich habe noch nicht an eine Lösung gedacht, also können Sie gerne eine in einem anderen Antwort -Thread vorschlagen.

So; Was ist die Modulecataloge überhaupt? Nur eine Liste zur Initialisierung und dann weggeworfen?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top