.net 遵循可靠原则的电子邮件回退

.net 遵循可靠原则的电子邮件回退,.net,asp.net-core,solid-principles,fallback,.net,Asp.net Core,Solid Principles,Fallback,我想实现一个微服务来使用回退客户端发送电子邮件,因此如果第一个客户端(SendGrid)出现故障,我将调用第二个客户端(MailJet),下面的代码显示了这个想法 问题是:有没有办法使用一些.net核心功能来改进主功能,而不是初始化新对象?关键是,我希望遵循坚实的原则,避免依赖和紧密耦合,因此,如果我明天需要一个新的EmailClient,它应该很容易实现,而不会打破坚实的原则 注:欢迎任何改进 using System; using System.Collections.Generic;

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

问题是:有没有办法使用一些.net核心功能来改进主功能,而不是初始化新对象?关键是,我希望遵循坚实的原则,避免依赖和紧密耦合,因此,如果我明天需要一个新的EmailClient,它应该很容易实现,而不会打破坚实的原则

注:欢迎任何改进

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;        
    }
}
使用系统;
使用System.Collections.Generic;
公共课程
{
公共静态void Main()
{       
列表客户端=新列表();
添加(新SendGrid());
clients.Add(newmailjet());
var emailService=新的emailService(客户端);
emailService.sendmail();
}   
}
公共类电子邮件服务
{
受保护名单客户;
公共电子邮件服务(列出客户端)
{
这个。客户=客户;
}
public void sendmail()
{
foreach(此.clients中的IEmailClient客户端)
{
if(client.send()){
打破
}
}
}
}
公共接口IEmailClient
{
bool-send();
}
公共类SendGrid:IEmailClient
{
公共bool send()
{
var错误=真;
Console.WriteLine(“SendGrid发送电子邮件”);
如果(错误){
控制台写入线(“错误”);
返回false;
}
Console.WriteLine(“发送的Sendgrid电子邮件”);
返回true;
}
}
公共类MailJet:IEmailClient
{
公共bool send()
{
var错误=错误;
Console.WriteLine(“Mailjet发送电子邮件”);
如果(错误){
控制台写入线(“错误”);
返回false;
}
Console.WriteLine(“已发送邮件”);
返回true;
}
}

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

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

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

这种设计的优点是,它允许在不更改类的情况下扩展
EmailService
的行为。您可以添加retrys、fallback、logging等,而无需更改现有代码。此外,如果
EmailService
最终只授权给
IEmailClient
,您甚至可能会质疑是否需要这样做

另一个优点是,它允许您动态创建具有不同行为的客户端。例如,假设您系统的用户希望能够配置回退、重试等。然后您可以拥有一个根据其配置动态构建
IEmailClient
实例的应用程序


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

有意为新开发人员实施设计模式。设计模式是描述性的,而不是规定性的。它们不是我们学习如何编写或识别好代码的方式,更不是我们学习自然语言语法的方式。关于改进,诸如manager和execute之类的术语并没有告诉我它实际上做了什么。目的/意图不明确。此外,列表的顺序是否重要?如何判断什么是主要系统,什么是后备系统?重复条目如何?还是零?或者50.。一些怎么样?@PeterBons这是一个微服务,它将发送事务性电子邮件,并且应该有一个备用客户端,以防默认客户端出现故障。我的主要问题是关于clients.add(new Client())部分,在PHP/Laravel中,我们可以设置一个提供程序来实例化它,我认为.net核心可能有类似的内容。感谢依赖项注入链接,它将useful@KevinKrumwiede,是两件截然不同的事情。从某种意义上说,它们是对立的。