You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动化向管理员发送多种表单邮件?泛型+AutoMapper方案是否可行?

你的泛型+AutoMapper方案完全可行,以下是具体实现步骤和验证

方案核心思路

通过泛型方法统一接收不同表单类型,借助AutoMapper将每种表单映射为包含Subject和Body的统一DTO,解耦表单类型与邮件内容生成逻辑,实现自动化发送。

具体实现步骤

1. 定义统一的邮件内容DTO

创建一个DTO承载邮件主题和正文,作为AutoMapper的目标类型:

public class EmailContentDto
{
    public string Subject { get; set; }
    public string Body { get; set; }
}

2. 配置AutoMapper映射规则

在AutoMapper配置类中,为每种表单类型配置对应的Subject和Body生成逻辑:

public class EmailMappingProfile : Profile
{
    public EmailMappingProfile()
    {
        // FeedBackForm 映射规则
        CreateMap<FeedBackForm, EmailContentDto>()
            .ForMember(dest => dest.Subject, opt => opt.MapFrom(src => $"Need consultation {src.Name}"))
            .ForMember(dest => dest.Body, opt => opt.MapFrom(src => $@"Name:  {src.Name}
Email: {src.Email}
Phone: {src.PhoneNumber}
Link:  {src.BotLink}"));

        // ContactsForm 映射规则
        CreateMap<ContactsForm, EmailContentDto>()
            .ForMember(dest => dest.Subject, opt => opt.MapFrom(src => $"Contact request from {src.FullName}"))
            .ForMember(dest => dest.Body, opt => opt.MapFrom(src => $@"Full Name: {src.FullName}
Email: {src.ContactEmail}
Message: {src.Message}"));
    }
}

3. 修改EmailService为泛型实现

注入IMapper,将原有方法改为泛型,通过AutoMapper获取邮件内容后统一发送:

public class EmailService : IEmailService, ITransientService
{
    private readonly IConfiguration _configuration;
    private readonly IMapper _mapper;

    public EmailService(IConfiguration configuration, IMapper mapper)
    {
        _configuration = configuration;
        _mapper = mapper;
    }

    public async Task SendFormToAdminEmailAsync<TForm>(TForm form)
    {
        // 映射表单到邮件内容DTO
        var emailContent = _mapper.Map<EmailContentDto>(form);
        if (emailContent == null || string.IsNullOrEmpty(emailContent.Subject) || string.IsNullOrEmpty(emailContent.Body))
        {
            throw new InvalidOperationException($"未配置类型 {typeof(TForm).Name} 的邮件内容映射规则");
        }

        var fromAddress = _configuration["EmailCredentials:Email"];
        var fromPassword = _configuration["EmailCredentials:Password"];
        var toAddress = new MailAddress("someAdminGmail@gmail.com");

        using var mail = new MailMessage(new MailAddress(fromAddress), toAddress)
        {
            Subject = emailContent.Subject,
            Body = emailContent.Body
        };

        using var smtp = new SmtpClient("smtp.gmail.com", 587)
        {
            Credentials = new NetworkCredential(fromAddress, fromPassword),
            EnableSsl = true
        };

        await smtp.SendMailAsync(mail);
    }
}

4. 额外优化建议

  • 类型约束:如果所有表单都实现了共同接口(如IFormWithContactInfo),可给泛型方法添加约束where TForm : IFormWithContactInfo,增强类型安全性。
  • 模板解耦:将邮件正文模板移到配置文件或资源文件中,通过AutoMapper自定义解析逻辑读取模板并填充参数,进一步降低耦合。
  • 异常处理:添加更细致的异常捕获与日志记录,方便排查发送失败问题。

方案验证结论

你的思路完全正确,这种实现方式:

  • 实现了代码复用,新增表单时仅需添加AutoMapper映射规则,无需修改邮件发送核心逻辑
  • 解耦了表单类型与邮件内容生成逻辑,符合开闭原则
  • 代码结构清晰,易于维护和扩展

内容的提问来源于stack exchange,提问作者Kirill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:33:25