【问题标题】:Adding events to an interface / implementation向接口/实现添加事件
【发布时间】:2009-12-30 09:10:27
【问题描述】:

知道以前有人问过这个问题,但是我的问题略有不同。

我有一个界面:

IEmailDispatcher

看起来像这样:

public interface IEmailDispatcher
{
    void SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary<string, byte[]> Attachments);
}

作为一点背景:

我有一个具有以下方法的静态 EmailDispatcher 类: SendEmail(string[] to, string fromName, string fromAddress, string subject, string body, bool bodyIsHTML, Dictionary Attachments);

这会通过 IoC 加载相关的 IEmailDispatcher 实现,并调用该方法。

然后我的应用程序可以简单地调用 EmailDispatcher.SendEmail(.........

我想向它添加事件,例如 OnEmailSent、OnEmailFail 等... 这样每个实现都可以处理发送电子邮件的成功和失败,并相应地记录它们。

我该怎么做呢?

或者,有没有更好的方法?

目前,我正在使用“BasicEmailDispatcher”,它基本上使用 System.Net 命名空间,创建一个 MailMessage,然后发送它。

将来,我将创建另一个类,以不同方式处理邮件...将其添加到用于报告等的 sql db 表中......因此将以不同于 BasicEmailDispatcher 的方式处理 OnEmailSent 事件

【问题讨论】:

    标签: c# events interface


    【解决方案1】:

    看起来试图将所有东西都放入静态类会让你在这里做一些尴尬的事情(具体来说,使用静态类实现the template pattern)。如果调用者(应用程序)只需要知道SendEmail 方法,那么接口中应该只有这些。

    如果确实如此,您可以让您的基本调度程序类实现模板模式:

    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() {}
    }
    

    更复杂的实现将分别从BasicEmailDispatcher 继承(并因此实现IEmailDispatcher)并覆盖一个或两个虚拟方法以提供成功或失败行为:

    public class EmailDispatcherWithLogging: EmailDispatcherBase {
        protected override OnEmailFailed() {
            // Write a failure log entry to the database
        }
    }
    

    【讨论】:

    • 我不确定如何实现这一点——我的静态类适合哪里?来自调用者的“入口点”......?比如我有BasicEmailDispatcher、DummyEmailDispatcher……他们还实现IEmailDispatcher吗?或 BaseEmailDispatcher...
    • 另外 - 导致每个 EmailSent 和 EmailFailed 事件的原因在每个实现中都会有所不同......
    • 抱歉 - 我有点误解了您的要求!在修改我的答案的过程中,我也试图澄清一下。至于你的静态类,这真的是一个单独的问题——你可以像以前一样继续使用它。 (虽然我建议在 StackOverflow 上阅读有关单例和依赖注入的信息!)
    【解决方案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);
    }
    

    更多详情请关注here.

    这就是你要找的答案吗?

    【讨论】:

      【解决方案3】:

      将事件添加到您的界面:

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

      在您的静态类中,使用显式事件访问器来订阅实际实现的事件:

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

      【讨论】:

        猜你喜欢
        • 2021-01-11
        • 2015-02-13
        • 2010-10-19
        • 2021-06-18
        • 2016-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多