65.9K
CodeProject 正在变化。 阅读更多。
Home

使用依赖注入在 .Net Core 中发送电子邮件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (11投票s)

2017年1月19日

CPOL

3分钟阅读

viewsIcon

49698

downloadIcon

719

本博客解释了如何使用依赖注入在 .Net Core 中发送电子邮件。

在构建网站时,您很有可能在某些时候需要电子邮件功能。有很多可用的电子邮件包可用于此任务。Dot Net Core 鼓励您使用依赖注入原则配置您的电子邮件或其他包。本博客将向您展示如何操作。

为什么选择依赖注入?

DI(依赖注入)帮助您创建松散耦合的应用程序模块。一个类在构造函数中接收对服务对象的接口引用,而不是创建对服务对象的新实例。这被称为显式依赖原则或“构造函数注入”。该类不知道服务对象,它只知道如何使用它。这使得测试和迁移到其他服务组件更加容易。Dot Net Core 完全支持依赖注入模式。服务在启动时注册。注册后,服务作为控制器类构造函数中的参数可用。稍后我会更详细地解释这一点。

演示应用程序

通过几个步骤,我创建了一个示例应用程序,我们可以在其中看到所有内容是如何工作的。我们分几个步骤构建应用程序。

  1. 创建演示 MVC 应用程序。
  2. 添加电子邮件包。
  3. 配置电子邮件设置。
  4. 创建电子邮件服务接口和类。
  5. 在启动时注册电子邮件服务。
  6. 在控制器中注入电子邮件服务。

创建演示 MVC 应用程序

启动 Visual Studio 并创建一个新的 MVC Core 应用程序。此演示不需要身份验证。

添加邮件包

我使用 MailKit 库进行此演示。它运行良好并且具有优雅的 API。从 nuget 安装邮件包。

pm> Install-Package NETCore.MailKit

在 appsettings.json 中配置电子邮件设置

最好使用配置文件在应用程序外部配置设置。在 .Net Core 中,设置被移动到 appsettings.json 文件。添加邮件设置是第一步。

...  
"Email": {
    "FromName": "<fromname>",
    "FromAddress": "<fromaddress>",

    "LocalDomain": "<localdomain>",

    "MailServerAddress": "<mailserveraddress>",
    "MailServerPort": "<mailserverport>",

    "UserId": "<userid>",
    "UserPassword": "<userpasword>"
  },
...

您可以使用自定义类读取设置。

public class EmailConfig
  {
    public String FromName { get; set; }
    public String FromAddress { get; set; }
    
    public String LocalDomain { get; set; }

    public String MailServerAddress { get; set; }
    public String MailServerPort { get; set; }

    public String UserId { get; set; }
    public String UserPassword { get; set; }
  }

EmailConfig 类用于在启动时读取设置。section 参数指定在 appsettings.json 文件中读取的位置。

 public void ConfigureServices(IServiceCollection services)
 {
   ...
   // Read email settings
   services.Configure<EmailConfig>(Configuration.GetSection("Email"));
   ...
 }

创建电子邮件服务接口和类

.Net Core DI 需要两项

  1. 接口。
  2. 实现类。

接口定义了可用的功能。实现类,顾名思义,实现了接口功能。

public interface IEmailService
{
  Task SendEmailAsync(string email, string subject, string message);
}

public class EmailService : IEmailService
{
  private readonly EmailConfig ec;

  public EmailService(IOptions<EmailConfig> emailConfig)
  {
    this.ec = emailConfig.Value;
  }

  public async Task SendEmailAsync(String email, String subject, String message)
  {
    try
    {
      var emailMessage = new MimeMessage();

      emailMessage.From.Add(new MailboxAddress(ec.FromName, ec.FromAddress));
      emailMessage.To.Add(new MailboxAddress("", email));
      emailMessage.Subject = subject;
      emailMessage.Body = new TextPart(TextFormat.Html) { Text = message };

      using (var client = new SmtpClient())
      {
        client.LocalDomain = ec.LocalDomain;

        await client.ConnectAsync(ec.MailServerAddress, Convert.ToInt32(ec.MailServerPort), SecureSocketOptions.Auto).ConfigureAwait(false);
        await client.AuthenticateAsync(new NetworkCredential(ec.UserId, ec.UserPassword));
        await client.SendAsync(emailMessage).ConfigureAwait(false);
        await client.DisconnectAsync(true).ConfigureAwait(false);
      }
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
    }
  }

构造函数参数 **IOptions<EmailConfig> emailConfig** 提供了轻松访问电子邮件设置的方法,而无需了解设置的配置位置或方式。MailKit 包用于实现实际的邮件发送。假设您想切换到其他邮件服务,您只需要更改此实现类即可。这完全符合单一职责原则。

在启动时注册电子邮件服务。

下一步是在启动时注册接口和实现类。

public void ConfigureServices(IServiceCollection services)
{
  ...
  // Register email service 
  services.AddTransient<IEmailService, EmailService>();
  ...
}

每次请求 IEmailService 引用时,都会提供一个 EmailService 实例。

在控制器中注入电子邮件服务

所有这些工作完成后,就是有趣的部分了。现在可以很容易地将电子邮件服务提供给控制器。只需在控制器构造函数中添加一个 IEmailService 参数,MVC 框架就会处理依赖注入!

public class HomeController : Controller
  {
    private readonly IEmailService _emailService;

    public HomeController(IEmailService emailService)
    {
      _emailService = emailService;
    }

设置断点,启动应用程序,调试器将显示一切按预期工作。

最后一步是实际使用电子邮件服务发送邮件。我制作了一个简单的输入表单和控制器上的操作处理程序来演示这一点。

[HttpPost()]
public async Task<IActionResult> Index(MailViewModel model)
{
  if (ModelState.IsValid)
  {
    await _emailService.SendEmailAsync(model.MailTo, model.Subject, model.Message);

    ViewBag.Succes = true;
  }
 
  return View(model);
}

我已经添加了源代码,以便您可以试用它。源代码基于 .Net Core 1.10。您可以在此处下载 SDK。

结论

您可以从使用 DI(依赖注入)原则配置的 .Net Core 应用程序发送邮件。Dot Net Core 原生支持 DI,无需第三方工具。DI 配置需要一些努力。作为回报,您将获得所有好处,例如松散耦合、单一职责和更好的测试可能性。

深入阅读

MailKit New is glue

wiki 依赖注入

Dot Net Core 依赖注入    

© . All rights reserved.