2017-09-12 2 views
-2

J'ai un objet (en fait un élément visuel et un élément viewmodel) que j'aimerais utiliser à plusieurs endroits dans mon projet. La fonction de l'objet est de collecter des informations de paiement. Le client Smith a commandé un widget de ma société, mais il est en retard avec le paiement. Il m'appelle pour dire qu'il paiera le montant en entier le 1er. Je remplis le montant et la date du paiement, clique sur un bouton et une entrée est ajoutée à ma base de données avec les informations de paiement proposées par M. Smith. Maintenant, comme je l'ai dit, je veux utiliser cet objet à plusieurs endroits, et selon l'endroit où je l'utilise, il se peut que je veuille plus après avoir cliqué sur le bouton Soumettre. Avec Widgets, je vends aussi Whatsits et Whoozits. Après avoir reçu les informations de paiement pour un Whatsit, je veux remplir une table supplémentaire qui enverra un rappel au client. Après avoir saisi les informations de paiement Whoozit, je souhaite remplir le tableau des rappels, en envoyant immédiatement au client une confirmation par SMS.Quand et pourquoi utiliser des gestionnaires d'événements personnalisés

Mon idée originale était simplement d'ajouter un champ List<Action> à mon objet d'origine, et en fonction de l'endroit auquel j'y accède, envoyez-lui toutes les actions supplémentaires que je veux faire après la mise à jour de la base de données originale.

Quelque chose comme ceci:

public class MoneyGetter 
{ 
    public List<Action> AfterEvents = new List<Action>(); 

    public void SavePaymentInfo() 
    { 
     //logic for initial database entry 

     foreach(var a in AfterEvents) 
     { 
      a.Invoke(); 
     } 
    } 
} 

Et après avoir créé l'objet, selon l'endroit où je l'utilise, je voudrais simplement ajouter

var mg = new MoneyGetter(); 
mg.AfterEvents.Add(() => { /* add situation specific action logic here */ }); 

Après avoir obtenu grâce à une partie de cela, il Il me semblait que c'est ce que les événements sont (je pense), et je devrais peut-être créer un événement OnSubmitted personnalisé pour mon objet MoneyGetter, en m'abonnant à cet événement de n'importe quel objet et en levant l'événement après l'entrée DB .

Est-ce le cas? Et si c'est le cas, pourquoi la création d'un gestionnaire d'événements personnalisé est-elle une meilleure idée que de simplement avoir un List<Action>?

+0

Vous n'avez pas besoin, vous pouvez toujours faire seulement args personnalisée qui étend de EventArgs et utilisez gestionnaire Buildin – sTrenat

+0

Auriez-vous d'utiliser MVVMlight? Il y a un Messenger intégré. – Fildor

+2

Oui, les événements sont censés être utiles dans ce scénario. Il n'y a aucune raison impérieuse que je vois qu'il doit être un événement personnalisé. Vous avez probablement eu cette mentalité parce que vous vous concentriez trop sur "ajouter". Les événements le font déjà d'eux-mêmes, tout ce dont vous avez besoin est l'opérateur + = pour vous abonner à l'événement. –

Répondre

0

Est-ce le cas?

Probablement, oui. Si vous souhaitez être en mesure d'informer les abonnés lorsqu'un événement se produit dans votre classe, le fait de déclencher un événement est une approche courante et efficace.

Et si oui, pourquoi la création d'un gestionnaire d'événements personnalisé est-elle une meilleure idée que de simplement avoir un List<Action>?

Eh bien, en ajoutant Action<T> s à une List<T> publique est en quelque sorte une façon alambiquée de mettre en œuvre des événements. Mais je suppose que cela fonctionnerait réellement. En tant que consommateur de votre classe, je m'attendais à pouvoir m'abonner à un événement en utilisant la syntaxe += au lieu d'avoir à ajouter/supprimer des actions d'un List<T> publiquement exposé.

+0

Je suis confus au sujet de cette dernière phrase. Je comprends que l'intention d'avoir une telle liste d'actions soit que ces actions soient effectuées quand l'événement se produit. Donc si par exemple il a une méthode publique avec laquelle les enregistreurs peuvent mettre des Actions à la liste, cela ferait un simple enregistrement des rappels. En ce sens, vous pouvez * "vous abonner" à cette liste, en fait. – Fildor

+0

Que voulez-vous dire? Comment l'abonné est-il censé être averti lorsque vous ajoutez une action à une liste? – mm8

+0

Il n'est pas censé être informé de cela. L'abonné ajoute une action. Dans l'OP, la liste est même publique. Donc, tout client pourrait simplement faire 'moneyGetterInstance.AfterEvents.Add (MyAction);' – Fildor

0

Qu'en est-il du modèle d'agrégateur d'événements? Je l'utilise assez souvent quand mes viewmodels doivent communiquer entre eux.

Caliburn.Micro a un poids léger intégré que vous pourriez utiliser. Si vous utilisez un conteneur IoC, il s'agit d'un snap pour vous assurer que chaque objet peut obtenir une référence à l'agrégateur d'événements et communiquer librement.

L'événement Aggregator

Caliburn.Micro est livré pré-empaquetés avec un événement Aggregator, appelé EventAggregator commodément. Pour ceux qui ne sont pas familiers, un agrégateur d'événements est un service qui offre la possibilité de publier un objet d'une entité à une autre d'une manière lâche. Événement Agrégateur est en fait un modèle et sa mise en œuvre peut varier de cadre à cadre. Pour Caliburn.Micro, nous nous sommes concentrés sur la simplicité de notre implémentation Event Aggregator sans sacrifier les fonctionnalités ni la flexibilité. Mise en route

Comme mentionné précédemment, nous fournissons une implémentation de l'événement Aggregator pour vous. Cette implémentation implémente l'interface IEventAggregator , cependant, vous pouvez fournir votre propre implémentation si nécessaire. Veuillez prendre un moment pour vous familiariser avec la signature IEventAggregator .

public interface IEventAggregator { 
    bool HandlerExistsFor(Type messageType); 
    void Subscribe(object subscriber); 
    void Unsubscribe(object subscriber); 
    void Publish(object message, Action<Action> marshal); 
} 

Information de: https://caliburnmicro.codeplex.com/wikipage?title=The%20Event%20Aggregator