Devity.Mailing provides a base service for sending template-based emails and a DI registration helper built on top of Devity.NETCore.MailKit.
Install-Package Devity.MailingThis package expects:
Devity.Extensionstemplates for email body generationDevity.NETCore.MailKitfor the underlying mail transport
CommonMailService: base class for your app-specific mail serviceDevityEmail: email payload with recipient, subject fragment, template, and attachmentsAddDevityMailing<T>(): DI registration helper
Derive your own service from CommonMailService.
using Devity.Extensions.Templates;
using Devity.Mailing;
using Devity.NETCore.MailKit.Core;
public sealed class AppMailService : CommonMailService
{
public AppMailService(IEmailService emailService)
: base(emailService, "My App | -TITLE-")
{
}
public Task SendWelcomeEmailAsync(string emailAddress, string firstName)
{
var template = new DevityTemplate("Templates/welcome.html")
.AddKey("-FIRSTNAME-", firstName);
var email = new DevityEmail(emailAddress, "Welcome", template);
return SendEmailAsync(email);
}
}subjectFormat must contain -TITLE-, because CommonMailService replaces that token with DevityEmail.SubjectMessage.
builder.Services.AddDevityMailing<AppMailService>(builder.Configuration);The package expects an Email configuration section in MailKitOptions format.
{
"Email": {
"Server": "smtp.example.com",
"Port": 587,
"SenderName": "My App",
"SenderEmail": "noreply@example.com",
"Account": "smtp-user",
"Password": "smtp-password",
"Security": true
}
}using Devity.NETCore.MailKit.Infrastructure.Internal;
builder.Services.AddDevityMailing<AppMailService>(new MailKitOptions
{
Server = "smtp.example.com",
Port = 587,
SenderName = "My App",
SenderEmail = "noreply@example.com",
Account = "smtp-user",
Password = "smtp-password",
Security = true
});DevityEmail supports chained attachment registration.
var email = new DevityEmail("user@example.com", "Invoice", template)
.AddAttachment("/tmp/invoice.pdf");SendEmailAsync sends HTML-only. For a multipart/alternative message with both an HTML and a
plain-text body, call SendMultipartEmailAsync from your derived service instead - it still uses
DevityEmail.Template for the HTML part, plus a separate plain-text string:
public Task SendWelcomeEmailAsync(string emailAddress, string firstName)
{
var template = new DevityTemplate("Templates/welcome.html")
.AddKey("-FIRSTNAME-", firstName);
var email = new DevityEmail(emailAddress, "Welcome", template);
var plainText = $"Welcome, {firstName}!";
return SendMultipartEmailAsync(email, plainText);
}An overload accepting a MailKitOptions (in place of the app's configured mail service) is
available too, mirroring SendEmailAsync's per-tenant-SMTP overload.
Both overloads take an optional extraHeaders (IDictionary<string, string>) for setting raw
message headers - e.g. RFC 8058 one-click unsubscribe:
var headers = new Dictionary<string, string>
{
["List-Unsubscribe"] = "<https://example.com/unsubscribe/abc123>",
["List-Unsubscribe-Post"] = "List-Unsubscribe=One-Click"
};
return SendMultipartEmailAsync(email, plainText, extraHeaders: headers);Email bodies are rendered with DevityTemplate.PopulateTemplate(). See ../Devity.Extensions/README.md for the full template API.