SideSoftware.Email
1.0.0
dotnet add package SideSoftware.Email --version 1.0.0
NuGet\Install-Package SideSoftware.Email -Version 1.0.0
<PackageReference Include="SideSoftware.Email" Version="1.0.0" />
<PackageVersion Include="SideSoftware.Email" Version="1.0.0" />
<PackageReference Include="SideSoftware.Email" />
paket add SideSoftware.Email --version 1.0.0
#r "nuget: SideSoftware.Email, 1.0.0"
#:package SideSoftware.Email@1.0.0
#addin nuget:?package=SideSoftware.Email&version=1.0.0
#tool nuget:?package=SideSoftware.Email&version=1.0.0
SideSoftware.Email
Overview
SideSoftware.Email is a .NET 10 library that provides a clean, injectable email service built on the Microsoft Graph API. It wraps Azure AD authentication and Graph API message sending behind a simple IEmailService abstraction, making it easy to send plain or HTML emails with attachments, CC/BCC recipients, and importance levels -- all through standard .NET dependency injection.
Installation
dotnet add package SideSoftware.Email
Quick Start
Register with configuration (appsettings.json)
using SideSoftware.Email.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGraphEmail(builder.Configuration);
Register with manual options
using SideSoftware.Email.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGraphEmail(options =>
{
options.TenantId = "your-tenant-id";
options.ClientId = "your-client-id";
options.ClientSecret = builder.Configuration["KeyVault:GraphEmailSecret"]!;
options.SenderAddress = "no-reply@contoso.com";
options.SenderDisplayName = "Contoso Notifications";
});
Send an email
using SideSoftware.Email.Abstractions;
app.MapPost("/api/send-email", async (IEmailService emailService) =>
{
var result = await emailService.SendAsync(
to: "recipient@contoso.com",
subject: "Hello from Graph API",
body: "<p>This email was sent using SideSoftware.Email.</p>");
return result.IsSuccess
? Results.Ok("Email sent successfully")
: Results.Problem(result.ErrorMessage);
});
Features
- Microsoft Graph API -- sends email through the Graph
/sendMailendpoint (no SMTP required) - Dependency injection -- registers via
IServiceCollection.AddGraphEmail()with configuration or manual options - Simple and advanced APIs -- quick
SendAsync(to, subject, body)overload for basic emails; fullEmailMessagemodel for complex scenarios - HTML and plain-text bodies with a single
IsHtmltoggle - File attachments -- attach any byte array with file name and content type
- Multiple recipients -- To, CC, and BCC with optional display names
- Reply-To support -- override the reply address independently from the sender
- Importance levels -- Low, Normal, or High priority
- Save to Sent Items -- configurable option to save sent messages in the sender's mailbox
- Result pattern --
EmailResultreturns success/failure with error details instead of throwing exceptions
Usage Examples
Simple Notification
Inject IEmailService into any service and send a quick HTML email:
using SideSoftware.Email.Abstractions;
public class NotificationService(IEmailService emailService)
{
public async Task NotifyAsync(string email, string name)
{
var result = await emailService.SendAsync(
to: email,
subject: "Record Updated",
body: $"""
<h2>Hi {name},</h2>
<p>Your record has been updated. Please review at your earliest convenience.</p>
<p>— Contoso</p>
""");
if (!result.IsSuccess)
{
throw new InvalidOperationException($"Failed to send email: {result.ErrorMessage}");
}
}
}
Rich Email with Attachments
Use EmailMessage for full control over recipients, attachments, and importance:
using SideSoftware.Email.Abstractions;
using SideSoftware.Email.Enums;
using SideSoftware.Email.Models;
public class ReportService(IEmailService emailService)
{
public async Task SendMonthlyReportAsync(byte[] pdfReport)
{
var message = new EmailMessage
{
To =
[
new EmailRecipient("bob@contoso.com", "Bob"),
new EmailRecipient("ops@contoso.com", "Operations")
],
Cc =
[
new EmailRecipient("admin@contoso.com")
],
Subject = $"Monthly Report - {DateTime.Now:MMMM yyyy}",
Body = """
<h2>Monthly Report</h2>
<p>Please find the attached monthly report.</p>
""",
IsHtml = true,
Importance = EmailImportance.High,
Attachments =
[
new EmailAttachment
{
FileName = $"Report-{DateTime.Now:yyyy-MM}.pdf",
Content = pdfReport,
ContentType = "application/pdf"
}
]
};
var result = await emailService.SendAsync(message);
if (!result.IsSuccess)
{
// Log, retry, or escalate as appropriate
}
}
}
Configuration
Add a GraphEmail section to your appsettings.json:
{
"GraphEmail": {
"TenantId": "your-azure-ad-tenant-id",
"ClientId": "your-azure-ad-client-id",
"ClientSecret": "your-azure-ad-client-secret",
"SenderAddress": "no-reply@contoso.com",
"SenderDisplayName": "Contoso Notifications",
"SaveToSentItems": true
}
}
| Property | Required | Default | Description |
|---|---|---|---|
TenantId |
Yes | -- | Azure AD Tenant ID |
ClientId |
Yes | -- | Azure AD Application (Client) ID |
ClientSecret |
Yes | -- | Azure AD Client Secret |
SenderAddress |
Yes | -- | Mailbox address to send from (e.g., no-reply@contoso.com) |
SenderDisplayName |
No | null |
Display name shown on sent emails |
SaveToSentItems |
No | true |
Whether to save sent messages in the sender's Sent Items folder |
Azure AD Setup
To use this library you need an Azure AD app registration with the Microsoft Graph Mail.Send application permission:
- Go to Azure Portal > Azure Active Directory > App registrations > New registration
- Name the application (e.g., "Graph Email Service") and register it
- Copy the Application (client) ID and Directory (tenant) ID into your configuration
- Go to Certificates & secrets > New client secret, copy the secret value into your configuration
- Go to API permissions > Add a permission > Microsoft Graph > Application permissions
- Search for and add Mail.Send
- Click Grant admin consent for your tenant
- Ensure the
SenderAddressmailbox exists in your Microsoft 365 tenant (a shared mailbox works well for this)
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Azure.Identity (>= 1.18.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.3)
- Microsoft.Graph (>= 5.103.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 91 | 2/28/2026 |