【问题标题】:Extending/overriding System.Net.Mail.SmtpClient Send(message As MailMessage) method扩展/覆盖 System.Net.Mail.SmtpClient Send(message As MailMessage) 方法
【发布时间】:2023-03-21 05:47:01
【问题描述】:

场景

大约 20 个 ASP.net(VB) 应用程序共享相同的代码框架,并且在部署时也共享一个通用的 web.config。在各种应用程序中,我们使用 System.Net.Mail.SmtpClient/MailMessage 来发送电子邮件,现在我们希望为我们的用户实现电子邮件退出功能,同时对现有代码进行最少的更改。这遗漏了最简单的方法;从 SmtpClient 继承一个类,比如 OurSmtpClient,并覆盖 Send() 方法以删除所有选择不接收电子邮件的用户,因为这意味着我们必须将所有 New SmtpClient() 更改为 New OurSmtpClient()应用程序。

替代品

我们之前使用 tagMapping 将标签重新映射到我们内部的派生替代品,类是否有类似的东西,以便所有 SmtpClient 自动成为 OurSmtpClient 并因此将使用覆盖的 Send() 方法?

我们也看过Extensions,但这里的问题是我们不能覆盖现有的方法,只能添加新的?

我们考虑过的下一个替代方案是反射,但我们无法考虑如何实际实施它。

Events .. 哦,如果有 Sending 事件...

代码(因为大家都喜欢)

这里是继承方法,只是为了理解我们在寻找什么:

Public Class OurSmtpClient
    Inherits SmtpClient

    Public Overloads Sub Send(message As MailMessage)
        For i As Integer = message.To.Count - 1 To 0 Step -1
            With message.To(i)
                If (.Address.Contains("test")) Then
                    message.To.RemoveAt(i)
                End If
            End With
        Next

        MyBase.Send(message)
    End Sub
End Class

有什么建议吗?如何在不更改现有应用程序中的代码且仅在共享代码(位于应用程序中的 App_Code 中)或共享 web.config 中的情况下做到这一点?

【问题讨论】:

  • 您的优先事项是什么,以最少的工作量完成这项工作,还是以灵活的方式完成这项工作,以便将来进一步改变?
  • 一个很好且有效的问题,Wiktor。当然,子类化 SmtpClient 让我们在未来添加额外功能方面处于更好的状态。但这也意味着现在可能不需要做很多工作。我们在这里谈论的是遍布许多应用程序的相当多行代码,虽然这是在 VS 和 Ctrl+H 中打开项目的问题,但这也意味着我们必须遵循我们所有的 Q/A、测试和部署例程这些应用程序。因此,我们希望减少执行此操作的工作量,这意味着只需更改共享框架和 web.config。
  • 您是否考虑过使用进行统计编织的 AOP 框架(如 PostSharp)?这将需要一些研究,但您现有的调用可能会被框架拦截,然后您可以创建一个特定的建议来处理您的自定义逻辑。不幸的是,我手头没有工作示例。
  • 谢谢你的建议,维克托。我偶然发现了那个替代方案,但没有仔细研究它,因为它需要添加一个额外的库。与 .NET 一样多才多艺,我希望有一个解决这个问题的方法,但似乎我们在这个问题上并不走运。
  • 如果我错了,请纠正我,但是 SmtpClient.Send 不是虚拟的,你打算如何覆盖它?

标签: asp.net .net vb.net


【解决方案1】:

我会在数据层而不是在邮件客户端进行更改。

我假设您将有关您的用户的所有信息集中存储在某个地方,以及他们不想再收到任何电子邮件的信息。因此,在我看来,只要您询问要向其发送电子邮件的用户列表,就可以不再简单地返回这些用户。

我对您当前应用程序的工作方式知之甚少,但这似乎是更改它的最方便的地方。

【讨论】:

  • +1.. 在发送功能是我阻止向退订者发送电子邮件的最后一个地方。当然,如果别无选择,那就另当别论了……
  • 好主意,是的,我们集中存储它。但是,这将需要许多代码更改,因为我们使用不同的方式来发送电子邮件并获取应该接收它们的用户/电子邮件。去掉“最少的改变......”的要求,我们有很多选择(包括你的建议)。但我们希望避免这种情况,这就是我问这个问题的原因。从 Git 统计数据中,我们得到了大约 350K 行代码。将其与测试、Q/A 和发布管理相结合,您就有了很多很多的工时。这就是我寻找 SmtpClient 的原因,因为这是共同点。
  • 我的角度是修改从数据库中获取数据的存储过程。查看一组仍以相同格式返回数据的存储过程意味着您不必通过 QA 和验证整个应用程序代码库。
  • 没错,@Grubsnik,但是,我们没有专门用于让用户使用电子邮件的 SP。它们更通用,如 GetUsersForApp,用于多种用途,包括发送电子邮件。不过感谢您的建议!
【解决方案2】:

您正在努力实现应该是一个简单的要求这一事实是您建立太多technical debt 的重要线索。您的帖子表达了对偿还技术债务的强烈意愿。这是您必须避免的事情,而是接受Merciless Refactoring。咬紧牙关,介绍专门的 SMTP 类。

【讨论】:

  • 猜你是对的......谢谢。我在谁应该获得奖励但决定分享之间犹豫不决; Grubsnik 因他的努力得到了赏金,而你得到了公认的答案。可能有人会抱怨,但我就是这么做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
相关资源
最近更新 更多