2009-03-10 5 views
1

Ich würde gerne eine Tauber-Implementierung für ein Ereignis von einer Instanz von "Authenticator" (im Folgenden "objAuthenticator") generiert.Registrierung auf "this" -Objekt eigenen Event-Handler innerhalb "dieser" Methode

Ist es eine akzeptable Praxis, eine solche Methode zur Verfügung zu stellen, die sich für die Behandlung von objAuthenticators eigenem Ereignis registriert, um eine taubere Implementierung bereitzustellen?

Und auch, wenn es eine akzeptable Praxis ist, habe ich zwei Follow-up-Fragen. Ich habe zwei überladene Methoden für "SendEmailOnAuthenticationFailed".

  • Welchen sollte ich der Außenwelt aussetzen?
  • Welcher würde weniger Kopplung zwischen Klassen verursachen?

    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]: Antwort auf Marc GRA Frage

Ich bin sehr verwirrt darüber, was Ihr Code versucht

Bisher zu tun "SendEmailOnAuthenticationFailed" ist nicht der Außenwelt ausgesetzt. Was ich versuche zu tun ist (ich habe gerade IsAuthenticated hinzugefügt) innerhalb "IsAuthenticated", wenn eine Authentifizierung fehlschlägt, möchte ich eine E-Mail senden, ohne überall den gleichen Event-Handler schreiben zu müssen.

[UPDATE2]: Ich habe erkannt, dass es nicht notwendig ist "AuthenticationFailed" auszusetzen. Ich werde die Klasse so geschlossen wie möglich halten, ohne das Ereignis zu offenbaren.

Warum können wir nicht mehr als eine Antwort als "Antwort" markieren? ...

[UPDATE3]: Endgültige Ausgabe: Hier ist die, wie ich beschlossen, zu implementieren.

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

Antwort

1

Die Antwort auf die erste Frage ist, dass es akzeptabel ist. Für Ihre Follow-ups ist die Antwort es hängt. Die erste Person verinnerlicht den E-Mail-Prozess. Wenn Sie dies tun, stellen Sie sicher, dass Sie die E-Mail-Logik injizieren. Wenn Sie Letzteres wählen, können Sie das Verhalten injizieren. Wenn Sie den zweiten tun, würde ich vorschlagen, dass Sie den Namen ändern, da es egal ist, ob es E-Mail oder MQ oder tiddlywinks ist. Tatsächlich wird die zweite Methode nicht wirklich benötigt, da sie direkt das Ereignis abonnieren können.

Wenn Sie über die Entkopplung besorgt sind, müssen Sie über die alleinige Verantwortung der Authenticator-Klasse nachdenken. Es sollte authentifizieren, keine E-Mails senden. Versuchen Sie folgendes:

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

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

jetzt verbrauchen Authentifikator:

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

Nein, das können sie nicht tun. AuthenticationFailed ist ein Event - es ist nicht von irgendwo aus zuweisbar, außer innerhalb der Klasse (wo sich derselbe Name tatsächlich auf das Feld bezieht). –

+0

guten Ruf. Die Antwort wurde korrigiert. –

+0

"Wenn Sie dies tun, stellen Sie sicher, dass Sie die E-Mail-Logik injizieren" -> ja, ich injiziere ein E-Mail-Objekt durch Konstruktor tatsächlich, über Code ist nur ein Demo-Code ich nur in einer Minute zusammengestellt. – Sung

1

Es ist ungewöhnlich, auf eigene Ereignisse zu hören; Diese Logik kann normalerweise in die OnAuthenticationFailed-Methode übernommen werden. Das heißt - ich bin sehr verwirrt darüber, was Ihr Code versucht zu tun, was macht es ein wenig schwer zu beantworten ...

Ich bezweifle es gilt, aber beachten Sie zusätzlich, dass es einige subtile synchronisation issues sind Sie vielleicht Sie müssen darüber nachdenken (wenn Sie mit Ihren eigenen Ereignissen sprechen), ob dieser Code stark gewunden ist (was nicht der Fall ist).

+0

I Frage aktualisiert haben Ihre Frage zu beantworten. – Sung

1

Ich glaube, ich habe deine Frage zum ersten Mal missverstanden ... bin ich richtig, wenn ich sage, dass du einen optionalen Weg dies zu tun willst? Persönlich vermute ich, ich würde, dass eine Option im Konstruktor:

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

Alternativ trennt die „E-Mail zu senden“ Funktionalität von der „Authentifizierung“ Funktionalität für eine bessere Trennung von Bedenken, und lassen Sie den Anrufer abonniert ein mit E-Mail-Handler, wenn sie möchten.Das ist wahrscheinlich eine bessere Lösung.

+0

Es war nicht nur ich, dann ... –

+0

Eigentlich habe ich gefragt, ob das Hören auf das eigene Objekt eine akzeptable Praxis ist oder nicht oder sogar üblich. Wenn es so ist, war ich nicht sicher, wie ich die Selbstereignisregistrierung der Außenwelt aussetzen könnte. – Sung

Verwandte Themen