微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

遵循 SOLID 原则的电子邮件回退

如何解决遵循 SOLID 原则的电子邮件回退

我想实现一个微服务来使用回退客户端发送电子邮件,因此如果第一个客户端 (SendGrid) 出现故障,我将调用第二个客户端 (MailJet),下面的代码展示了这个想法。

问题是:有没有办法使用一些 .net 核心功能而不是初始化新对象来改进 Main 函数?关键是我想遵循 SOLID 原则,避免依赖和紧密耦合,所以如果我明天需要一个新的 EmailClient,它应该很容易实现,而不会违反 SOLID 原则。

附言欢迎任何改进。

using System;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {       
        List<IEmailClient> clients = new List<IEmailClient>();
        clients.Add(new SendGrid());
        clients.Add(new MailJet());
        
        var emailService = new EmailService(clients);
        emailService.sendEmail();
    }   
}

public class EmailService
{
    protected List<IEmailClient> clients;
    
    public EmailService(List<IEmailClient> clients)
    {
        this.clients = clients;
    }
    
    public void sendEmail()
    {
        foreach (IEmailClient client in this.clients)
        {
            if (client.send()) {
                break;
            }
        }
    }
}

public interface IEmailClient
{
    bool send();
}

public class SendGrid: IEmailClient
{
    public bool send()
    {
        var error = true;

        Console.WriteLine("SendGrid sending email");

        if (error) {
            Console.WriteLine("Error");     
            return false;
        }
        
        Console.WriteLine("Sendgrid email sent");
        return true;        
    }
}

public class MailJet: IEmailClient
{
    public bool send()
    {
        var error = false;

        Console.WriteLine("Mailjet sending email");

        if (error) {
            Console.WriteLine("Error");     
            return false;
        }
        
        Console.WriteLine("Mailjet email sent");
        return true;        
    }
}

dotnet fiddle

解决方法

所有应用程序都有一个 Composition Root,用于连接依赖项。无论您是手动编写还是通过配置 IoC 容器,您的代码核心很可能都是相同的。

在您设计的示例中,Main 方法是组合根,添加新的 IEmailClient 实现不会影响应用程序的核心 (EmailService),只会影响根。>

现在关于设计,很难说,但也许您可以努力应用 CompositeDecorator 模式来抽象出多个客户端的存在。例如:

enter image description here

这种设计的优点是它允许在不改变类的情况下扩展 EmailService 的行为。您可以在不更改现有代码的情况下添加重试、回退、日志记录等。此外,如果 EmailService 最终只委托给 IEmailClient,您甚至可能会质疑是否需要 Facade

另一个优点是它可以让您即时创建具有不同行为的客户端。例如,假设您的系统用户希望能够配置回退、重试等。那么您可以使用 Factory 根据他们的配置动态构建 IEmailClient 实例。

但是,请记住不要过度设计解决方案。您已经在利用现有的电子邮件网关。如果您不确定自己需要什么,请努力寻找最简单的解决方案并根据需要进行重构。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。