2009-03-10 3 views
1

Je souhaite fournir une implémentation deafult pour un événement généré par une instance de "Authenticator" (ci-après "objAuthenticator").Inscription au gestionnaire d'événements propre à "cet" objet dans la méthode "this"

Est-ce une pratique acceptable pour fournir une telle méthode qui s'enregistre pour gérer le propre événement d'objAuthenticator afin de fournir une implémentation plus transparente?

Et aussi, si c'est une pratique acceptable, j'ai deux questions de suivi. J'ai deux méthodes surchargées pour "SendEmailOnAuthenticationFailed".

  • Lequel dois-je exposer au monde extérieur?
  • Lequel provoquerait moins de couplage entre les classes?

    public class Authenticator 
    { 
         public event EventHandler AuthenticationFailed = delegate { }; 
         protected virtual void OnAuthenticationFailed() 
         { 
          var handler = AuthenticationFailed; 
          handler(this, EventArgs.Empty); 
         } 
    
         public void IsAuthenticated() 
         { 
          // Some logic... 
          // ... 
          // Woops authentication failed 
          OnAuthenticationFailed(); 
         } 
    
    
         // Is this a better option? 
         public void SendEmailOnAuthenticationFailed() 
         { 
          SendEmailOnAuthenticationFailed(EmailSender); 
         } 
    
         // Or is this? 
         public void SendEmailOnAuthenticationFailed(EventHandler emailSender) 
         { 
          AuthenticationFailed += emailSender; 
         } 
    
         private void EmailSender(object sender, EventArgs e) 
         { 
          Console.WriteLine("Send email: EmailSender"); 
         } 
        } 
    

[UPDATE]: Réponse à la question

Marc Gravell Je suis très confus au sujet de ce que votre code essaie de faire

Jusqu'à présent , "SendEmailOnAuthenticationFailed" n'est pas exposé au monde extérieur. Ce que j'essaie de faire est que (je viens d'ajouter IsAuthenticated) dans "IsAuthenticated", quand une authentification échoue, je voudrais envoyer un email sans avoir à écrire le même gestionnaire d'événement partout.

[MAJ2]: Je me suis rendu compte qu'il n'y a pas besoin d'exposer "AuthenticationFailed". Je vais garder la classe aussi fermée que possible sans exposer l'événement. Pourquoi ne pas marquer plus d'une réponse comme «réponse»? ...

[Update3]: Sortie finale: Voici la façon dont j'ai décidé de mettre en œuvre.

public class Authenticator 
{ 
    private readonly IEmailResponder _EmailResponder; 

    public Authenticator(IEmailResponder emailResponder) 
    { 
     _EmailResponder = emailResponder; 
    } 

    public void IsAuthenticated() 
    { 
     // Some logic... 
     // ... 

     // Woops authentication failed 
     SendEmailForAuthenticationFailure(); 
    } 

    private void SendEmailForAuthenticationFailure() 
    { 
     _EmailResponder.SendEmail(...); 
    } 
} 

Répondre

1

La réponse à la première question est que c'est acceptable. Pour vos suivis, la réponse est cela dépend. Le premier internalise le processus d'email. Si vous choisissez de le faire, assurez-vous que vous injectez la logique de messagerie. Si vous choisissez ce dernier, il vous permet d'injecter le comportement. Si vous faites le second, cependant, je suggère que vous changiez le nom, car ce n'est pas grave si c'est email, ou MQ, ou tiddlywinks. En fait, la seconde méthode n'est pas vraiment nécessaire, puisqu'ils peuvent s'abonner directement à l'événement.

Si vous êtes préoccupé par le découplage, vous devez penser à la responsabilité unique de la classe Authenticator. Cela devrait être pour authentifier, pas pour envoyer des emails. Essayez ceci:

public class Authenticator 
{ 
    public event EventHandler AuthenticationFailed = delegate { }; 

    protected virtual void OnAuthenticationFailed() 
    { 
     AuthenticationFailed(this, EventArgs.Empty); 
    } 
} 

maintenant, authentificateur consomment:

AuthenticationEmailResponder responder = new AuthenticationEmailResponder(emailAddress, emailServer); 
objAuthenticator.AuthenticationFailed += responder.SendFailureMessage; 
+0

Non, ils ne peuvent pas faire cela. AuthenticationFailed est un événement - il n'est pas assignable de n'importe où sauf à l'intérieur de la classe (où le même nom fait référence au champ). –

+0

bon appel. Correction de la réponse –

+0

"Si vous choisissez de faire cela, assurez-vous que vous injectez la logique de messagerie" -> oui, j'injecte un objet emailer par le constructeur en fait, ci-dessus le code est juste un code démo que je viens de rassembler en une minute. – Sung

1

Il est inhabituel d'écouter vos propres événements; une telle logique peut généralement aller dans la méthode OnAuthenticationFailed. Cela dit - je suis très confus au sujet de ce que votre code essaie de faire, ce qui en fait une subtile synchronisation issues un peu difficile à répondre ...

Je doute qu'il applique, mais Aussi, notez que vous pourriez sont besoin de réfléchir (en parlant à vos propres événements) si ce code est fortement enfilé (ce qui n'est pas le cas).

+0

J'ai mis à jour la question de répondre à votre question. – Sung

1

Je pense que j'ai mal compris votre question la première fois ... ai-je raison de dire que vous voulez un optionnel façon de faire? Personnellement, je pense que je ferais qu'une option dans le constructeur:

public class Authenticator 
{ 
    public event EventHandler AuthenticationFailed = delegate { }; 

    public Authenticator(bool sendEmailOnFailure) 
    { 
     if (sendEmailOnFailure) 
     { 
      // No need for the no-op delegate any more, so just replace it. 
      AuthenticationFailed = EmailSender; 
     } 
    } 
} 

Vous pouvez également séparer la fonctionnalité « e-mail d'envoi » de la fonctionnalité « d'authentification » pour une meilleure séparation des préoccupations, et de laisser l'appelant souscrire à l'aide d'un gestionnaire d'email s'ils le veulent.C'est probablement une solution plus propre.

+0

Ce n'était pas seulement moi, alors ... –

+0

En fait, je demandais si écouter l'événement de son propre objet est une pratique acceptable ou pas ou même habituelle. si c'est le cas, je ne savais pas comment exposer l'enregistrement d'événements personnels au monde extérieur. – Sung

Questions connexes