2010-11-15 11 views
1

J'essaye de faire en sorte que mon IEventAggregator me permette de publier et d'événement dans un module et de l'attraper dans un autre. J'ai essayé mon code ci-dessous dans un seul module/projet et cela fonctionne très bien. Il échoue seulement quand j'ai un module/projet publie l'événement et un autre s'abonne à lui.IEventAggregator n'atteint pas les modules

J'ai mon IEventAggregator injecté dans les deux modules via l'unité.

J'ai 3 projets, dont deux d'entre eux ont des modules (les appeler A et B) et un est juste une bibliothèque de classe ordinaire (appeler Interfaces)

Dans la bibliothèque de classe Interfaces il y a ce code:

public class RandomTestEvent : CompositePresentationEvent<string> 
{ 
} 

dans le module a il y a ce code dans un bouton de commande de clic (ce qui est vraiment dans une vue modèle dans le projet):

var evt2 = _eventAggregator.GetEvent<RandomTestEvent>(); 
evt2.Publish("Testing"); 

Dans le module B il y a ce code:

public void Initialize() 
    { 
     var evt2 = _eventAggregator.GetEvent<RandomTestEvent>(); 
     evt2.Subscribe(OnRandomThingDone); 
    } 

    private void OnRandomThingDone(string obj) 
    { 
     MessageBox.Show("Random Event Done With: " + obj);    
    } 

Je peux tracer à travers et je vois s'Abonnez-vous appelé. Quand je regarde Publish geting appelé le débogueur dit Subscriptions = 1 (donc il sait que l'abonnement a été fait, donc je ne semble pas avoir 2 instances différentes de IEventAggregator.)

Mais OnRandomThingDone n'est jamais appelé après Publier.

Une idée pourquoi? (Ai-je besoin d'envoyer plus de code?) Si oui, faites le moi savoir.

+0

Abonnez-vous à l'événement dans le même module et voir si votre code est appelé. Cela vous indiquera dans quel module se trouve le problème. – ihatemash

Répondre

7

Vraiment aléatoire - votre abonné obtient GC'd avant la publication de l'événement - puisque le comportement par défaut de CompositePresentationEvent de Prism est d'utiliser WeakReferences pour préserver références de cible d'abonné. Alors ... essayez d'appeler la surcharge Subscribe qui vous permet de spécifier keepSubscriberReferenceAlive et de passer en vrai. Si votre abonné reçoit ensuite l'événement avec succès, cela signifie que votre classe qui contient OnRandomThingDone est hors de portée et obtient GC'd avant la publication de l'événement.

référence API au hasard: http://msdn.microsoft.com/en-us/library/ff921122(PandP.20).aspx

+0

Vous êtes AWSOME! C'était exactement ça! Merci! – Vaccano

+0

La raison pour laquelle votre abonné est GC'd est que cela fait partie de la classe de module qui n'est disponible que lorsque Prism bootstraps. En passant true dans subscribe, vous forcez l'abonnement à l'événement pour maintenir le module actif. Une meilleure option pourrait s'abonner à l'événement dans un composant qui est enregistré avec le unityconainer avec un ContainerControlledLifetime –

0

Il n'a rien à voir avec GC car une fois Subsriber est attaché référence à elle ne meurt jamais. Le vrai problème est dû à l'inaccessibilité du OnRandomThingDone si DOIT être publique i.e.:

**public** void OnRandomThingDone(string obj) 
{ 
    MessageBox.Show("Random Event Done With: " + obj);    
} 
+1

En fait, non. @ JeffN825 est correct; les abonnés sont conservés comme une référence faible. Bien que le code de Vaccano ne l'affiche pas, la méthode Subscribe prend en fait une action sur la méthode, ce qui signifie que la méthode n'a pas besoin d'être publique. Donc, votre message est faux. –

1

En fait grimcoder est correct, une référence faible nécessite une méthode d'action publique. L'utilisation d'une référence de semaine libère le codeur de la désinscription de l'événement, celle-ci est gérée par le GC.

Vous pouvez cependant utiliser une référence forte en transmettant true à keepSubscriberReferenceAlive, qui peut également accélérer votre programme si un grand nombre d'événements est appelé dans un court laps de temps.

Pour plus d'informations sur ce voir: Chapter 9: Communicating Between Loosely Coupled Components Section Références fortes En utilisant Se abonner