Adding events to an interface / implementation
Know this has been asked before, however my question is slightly different.
I have an interface:
IEmailDispatcher
It looks like this:
public interface IEmailDispatcher
{
void SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary<string, byte[]> Attachments);
}
As a bit of background:
I have a static EmailDispatcher class that has the method: SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary Attachments);
This, throught IoC, then loads the relevant IEmailDispatcher implementation, and calls that method.
My applications can then simply call EmailDispatcher.SendEmail(.........
I want to add events to it, for example OnEmailSent, OnEmailFail etc... So that each implementation can handle successes and failures of sending emails, and log them accordingly.
How would I go about doing this?
Or, is there a better way?
At the moment, I'm using a "BasicEmailDispatcher" that basically uses the System.Net namespaces, creates a MailMessa开发者_如何学JAVAge, and sends it.
In the future, I will create another class, that handles mail differently... adds it to a sql db table for reporting etc.... and so will handle the OnEmailSent events differently to the BasicEmailDispatcher
It looks like trying to fit everything into the static class is making you do awkward things here (specifically, implementing the template pattern using a static class). If callers (applications) only need to know about the SendEmail
method, that's the only thing that should be in the interface.
If that is indeed the case, you can just make your base dispatcher class implement the template pattern:
public class EmailDispatcherBase: IEmailDispatcher {
// cheating on the arguments here to save space
public void SendEmail(object[] args) {
try {
// basic implementation here
this.OnEmailSent();
}
catch {
this.OnEmailFailed();
throw;
}
}
protected virtual void OnEmailSent() {}
protected virtual void OnEmailFailed() {}
}
More complex implementations would each inherit from BasicEmailDispatcher
(and therefore implement IEmailDispatcher
) and override one or both of the virtual methods to provide success or failure behavior:
public class EmailDispatcherWithLogging: EmailDispatcherBase {
protected override OnEmailFailed() {
// Write a failure log entry to the database
}
}
public interface IEmailDispatcher
{
event EventHandler EmailSent;
void SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary<string, byte[]> Attachments);
}
For more details, look here.
Is this the answer you were looking for?
Add the events to your interface :
public interface IEmailDispatcher
{
void SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary<string, byte[]> Attachments);
event EmailSentEventHandler EmailSent;
event EmailFailedEventHandler EmailFailed;
}
And in your static class, use explicit event accessors to subscribe to the events of the actual implementation :
public static class EmailDispatcher
{
public event EmailSentEventHandler EmailSent
{
add { _implementation.EmailSent += value; }
remove { _implementation.EmailSent -= value; }
}
public event EmailFailedEventHandler EmailFailed
{
add { _implementation.EmailFailed += value; }
remove { _implementation.EmailFailed -= value; }
}
}
精彩评论