Click here to Skip to main content
14,031,046 members
Click here to Skip to main content
Add your own
alternative version

Stats

21.4K views
394 downloads
22 bookmarked
Posted 18 Jan 2017
Licenced CPOL

Send email with .Net Core using Dependency Injection

, 18 Jan 2017
Rate this:
Please Sign up or sign in to vote.
This blog explains how you can send email with .Net Core using Dependency Injection

When you build a website, there is a big chance that you need email functionality at some point. There are many email packages available for you for this task. Dot Net Core encourages you to configure your email, or other packages using the Dependency Injection principle. This blog shows you how.

Why Dependency Injection?

DI (Dependency Injection) helps you to create loosely coupled application modules. A class receives in the constructor a interface reference to the service object, rather then creating new instance to the service object. This is know as the Explicit Dependencies Principle or "constructor injection". The class has no knowledge about the service object, it just knows how to use it. This makes testing and migrating to an other service component much easier. Dot Net Core fully embrace the Dependency Injection patern. The service is registered during startup. After registration is the service available as a parameter in the controller class constructor. I explain this later in more detail.

Demo Application

With several steps I create a sample application, where we can see how it all works. We build the application in serveral steps.

  1. Create demo MVC application.
  2. Add email package.
  3. Configure email settings.
  4. Create email service interface and class.
  5. Register email service in startup.
  6. Inject email service in controller.

Create demo MVC application

Start Visual Studio and create a new MVC Core application. Authentication is not needed for this demo

Add mail package

I use the MailKit library for this demo. It works well and has an elegant API. Install the mail package from nuget:

pm> Install-Package NETCore.MailKit

Configure email settings in appsettings.json

It's good pratice to configure settings outside the application using a config file. In .Net Core settings are moved to the appsettings.json file. Adding the mail settings is the first step.

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

    "LocalDomain": "<localdomain>",

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

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

You can read the settings with a customized class.

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; }
  }

The EmailConfig class is used for reading the settings during startup. The section parameter specifies where to read within the appsettings.json file.

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

Create email service interface and class

.Net Core DI requires two items:

  1. Interface.
  2. Implementing class.

The interface defines the available functionality. The implementing class, as the name implies implements the interface functionality.

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);
    }
  }

The constructor parameter IOptions<EmailConfig> emailConfig provides easy access to the emailsettings without knowing where or how the settings are configured. The MailKit package is used to implement the actual mailing. Supose you want to switch to an other mail service, you only need to change this implementation class. This perfectly fits the Single Responsibility principle.

Register email service in startup.

The next step is to register the interface and the implementation class during startup.

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

Every time a IEmailService reference is requested, a EmailService instance delivered.

Inject email service in controller

After all this works comes the fun part. It's now very easy to make the emailservice available to a controler. Just add a IEmailService parameter in the controller constructor and the MVC framework takes care of the dependency injection!

public class HomeController : Controller
  {
    private readonly IEmailService _emailService;

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

Set a breakpoint, start the application and the debugger shows it's all working as expected:

The last step is to actually use the email service for sending a mail. I made simple input form and an action handler on the controller to demonstrate this.

[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);
}

I added the source code so you can play with it. The source code is base on .Net Core 1.10. You can download de SDK here.

Conclusion

You can send mail from a .Net Core application, configured with the DI (Dependency Injection) principle. Dot Net Core supports DI out of the box, there is no need for third party tooling. The DI configuration takes some effort. In return you get all the benefits such as loosely coupling, Single Point of Resposibility and better testing possibilities.

Further reading

MailKit New is glue

wiki deendency injection

Dot Net Core dependency injection    

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bart-Jan Brouwer
Technical Lead
Netherlands Netherlands
I graduated as Bachelor of Mechanical Engineering. Soon I moved from mechanical to software engineering. With more than 20 years of experience in software design, development, and architecture I love building software that users enjoy en suit their needs.

Comments and Discussions

 
QuestionDI - Lifetime Pin
dogahas3-Sep-18 21:40
memberdogahas3-Sep-18 21:40 
SuggestionMore comfort in sending email with .Net Core Pin
axuno5-Nov-17 4:09
memberaxuno5-Nov-17 4:09 
QuestionImplementing errors Pin
web_11127-Feb-17 5:23
memberweb_11127-Feb-17 5:23 
AnswerRe: Implementing errors Pin
Bart-Jan Brouwer7-Mar-17 2:37
memberBart-Jan Brouwer7-Mar-17 2:37 
QuestionAny Razor support Pin
Layinka24-Jan-17 5:12
memberLayinka24-Jan-17 5:12 
AnswerRe: Any Razor support Pin
Bart-Jan Brouwer25-Jan-17 19:18
memberBart-Jan Brouwer25-Jan-17 19:18 
QuestionMail Header Control Pin
JohnnySandaire20-Jan-17 8:14
memberJohnnySandaire20-Jan-17 8:14 
AnswerRe: Mail Header Control Pin
Bart-Jan Brouwer22-Jan-17 19:56
memberBart-Jan Brouwer22-Jan-17 19:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190419.4 | Last Updated 19 Jan 2017
Article Copyright 2017 by Bart-Jan Brouwer
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid