3

Sending Mails In Aspnetcore

 2 years ago
source link: https://www.yvesdennels.com/posts/sending-mails-aspnetcore/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Sending Mails In Aspnetcore

This post is part of series starting here.

Here’s how I configure my mailers in a ASP.Net Core project developed in F#. I define an interface:

type IMailer =
    // to * subject * body
    abstract Send: string * string * string -> unit

of which I have 2 implementation. The first one is for development as it simply prints the mail on the server’s standard output:

type ConsoleMailer() =
    interface IMailer with
        member _.Send(recipient, subject, body) =
            printfn "Sending mail:\nTo:%s\nSubject:%s\n%s" recipient subject body

The second implementation is for production:

  open MailKit.Net.Smtp
  open MailKit
  open MimeKit

  type ProductionMailer(host:string, port:int, login:string,password:string) =
    interface IMailer with
        member _.Send(recipient, subject, body) =
            let message = new MimeMessage()

            message.From.Add (new MailboxAddress ("ProjectName", "[email protected]"))
            message.To.Add (new MailboxAddress ("", recipient));
            message.Subject <- subject
            message.Body <- new TextPart("plain",Text=body)
            try
                let client = new SmtpClient()
                client.Connect(host,port,true)
                client.Authenticate(login,password)
                client.Send(message)|> ignore
                client.Disconnect(true)
            with e ->
                printfn "Exception: %A" e

and its config is set in a JSON file handled by this code:

open FSharp.Data
type MailConfig = JsonProvider<"config/mail.json.sample", EmbeddedResource="lib, lib.embedded.mail.json.sample">

It uses a type provider using the project’s provided sample config file, which is

{
    "host":"mail.example.com",
    "port": 25,
    "login": "username",
    "password": "superpass"
}

With all building block available, we can then inject them in the application in the Startup class' ConfigureServices method.

       if env.IsDevelopment() then
            services.AddTransient<IMailer,ConsoleMailer>() |> ignore
        else
            let mailConfigFile = Environment.GetEnvironmentVariable("WADESDA_MAIL_CONFIG_FILE")
            if not (isNull mailConfigFile) && System.IO.File.Exists(mailConfigFile) then
                let mailConfig = MailConfig.Load(mailConfigFile)
                let mailer =
                    ProductionMailer(mailConfig.Host,
                                     mailConfig.Port,
                                     mailConfig.Login,
                                     mailConfig.Password
                    )
                services.AddTransient<IMailer>(fun s ->  mailer :> IMailer) |> ignore

We inject the dependency as transient so that every request for an instance gets a new one. And that’s it. In the app, you fist need to get a handle on the mailer. In WebSharper, you do it like this:

        let httpContext:Microsoft.AspNetCore.Http.HttpContext = ctx.HttpContext()
        let serviceProvider= httpContext.RequestServices
        let mailer = serviceProvider.GetService(typeof<IMailer>)

Sending a mail is then done like this:

mailer.Send(emailAddress,subject, body)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK