Adding events to an interface / implementation

北城余情 提交于 2019-12-23 03:22:12

问题


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 MailMessage, 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


回答1:


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



回答2:


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?




回答3:


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


来源:https://stackoverflow.com/questions/1975922/adding-events-to-an-interface-implementation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!