Nasps.MailSender.Package
1.1.2
dotnet add package Nasps.MailSender.Package --version 1.1.2
NuGet\Install-Package Nasps.MailSender.Package -Version 1.1.2
<PackageReference Include="Nasps.MailSender.Package" Version="1.1.2" />
<PackageVersion Include="Nasps.MailSender.Package" Version="1.1.2" />
<PackageReference Include="Nasps.MailSender.Package" />
paket add Nasps.MailSender.Package --version 1.1.2
#r "nuget: Nasps.MailSender.Package, 1.1.2"
#:package Nasps.MailSender.Package@1.1.2
#addin nuget:?package=Nasps.MailSender.Package&version=1.1.2
#tool nuget:?package=Nasps.MailSender.Package&version=1.1.2
Nasps.MailSender.Package
A reusable, dynamic .NET NuGet package for sending emails and notifications using MailKit. It provides a clean API for sending plain text, HTML, and built-in style Arabic email templates.
What This Package Does
Nasps.MailSender.Package is a fully self-contained email sending library. Once installed and configured, you write zero boilerplate — no SMTP client, no template HTML, no service class. The package provides:
| Capability | Description |
|---|---|
| Direct Async Send | await _mailService.SendOtpEmailAsync(...) — awaited, result returned |
| Fire-and-Forget Queue | _mailQueue.EnqueueOtp(...) — returns immediately, sent in background |
| Automatic Retries | Configurable Polly retry policy on transient SMTP failures |
| 5 Built-in Arabic Templates | Welcome, OTP, Reset Password, Create Password, Notification |
| Brand Customization | Your logo, colors, name, and footer via appsettings.json |
| Fluent Email Builder | Chain .To().Subject().HtmlBody().Attach().Build() |
Architecture Overview
Your Service / Controller
│
├─── ISmtpMailService ──► SmtpMailService ──► MailKit SMTP
│ (direct, awaited) │
│ └── Polly Retry (3x, 2s delay)
│
└─── IMailQueue ──► BackgroundMailQueue (Channel<T>)
(fire & forget) │
MailSenderBackgroundService (IHostedService)
│
ISmtpMailService (drain + send)
All services are registered automatically by AddNaspsMailSender(...). You never need to instantiate anything manually.
Installation
dotnet add package Nasps.MailSender.Package
Quick Start (3 Steps)
Step 1 — Configure appsettings.json
{
"SmtpSettings": {
"Host": "smtp.gmail.com",
"Port": 587,
"EnableSsl": true,
"UserName": "your-email@gmail.com",
"Password": "your-app-password",
"FromEmail": "your-email@gmail.com",
"FromName": "Nasps System",
"UseDefaultCredentials": false,
"RetryCount": 3,
"RetryDelaySeconds": 2,
"QueueCapacity": 500
},
"EmailTemplateSettings": {
"ProjectName": "اسم الجهة/النظام",
"ProjectSubtitle": "المنصة الرسمية",
"SupportEmail": "support@nasps.org.eg",
"LogoUrl": "https://example.com/logo.png",
"PrimaryColor": "#0d6efd",
"PrimaryColorDark": "#0a58ca",
"AccentColor": "#4caf3a",
"AccentColorDark": "#2e7d23",
"FooterText": "جميع الحقوق محفوظة",
"CompanyName": "Nasps",
"WebsiteUrl": "https://nasps.org.eg"
}
}
Step 2 — Register in Program.cs
using Nasps.MailSender.Package.Extensions;
var builder = WebApplication.CreateBuilder(args);
// One line — registers everything (ISmtpMailService, IMailQueue, background service)
builder.Services.AddNaspsMailSender(builder.Configuration);
Step 3 — Inject and Use
using Nasps.MailSender.Package.Abstractions;
public class AuthService
{
private readonly ISmtpMailService _mail; // direct, awaited
private readonly IMailQueue _queue; // fire-and-forget
public AuthService(ISmtpMailService mail, IMailQueue queue)
{
_mail = mail;
_queue = queue;
}
public async Task SendOtpAsync(string email, string code)
{
// Option A: await the result
var result = await _mail.SendOtpEmailAsync(email, "ياسمين", code, expiryMinutes: 10);
if (!result.IsSuccess)
throw new Exception(result.ErrorMessage);
// Option B: fire-and-forget (non-blocking)
_queue.EnqueueOtp(email, "ياسمين", code, expiryMinutes: 10);
}
}
ISmtpMailService — Direct Send API
Inject ISmtpMailService for awaited, result-returning sends.
Built-in Arabic Template Methods
// Welcome Email
await _mail.SendWelcomeEmailAsync(
to: "user@example.com",
userName: "name"
);
// OTP / Verification Code
await _mail.SendOtpEmailAsync(
to: "user@example.com",
userName: "name",
otpCode: "485921",
expiryMinutes: 10
);
// Reset Password
await _mail.SendResetPasswordEmailAsync(
to: "user@example.com",
userName: "name",
resetPasswordUrl: "https://example.com/reset?token=abc",
expiryHours: 1
);
// Create Password (for new accounts)
await _mail.SendCreatePasswordEmailAsync(
to: "user@example.com",
userName: "name",
createPasswordUrl: "https://example.com/create-password?token=xyz",
expiryHours: 24
);
// General Notification with CTA button
await _mail.SendNotificationEmailAsync(
to: "user@example.com",
userName: "name",
title: "تم تحديث الطلب",
body: "لقد تم تحديث حالة طلبك بنجاح.",
actionUrl: "https://example.com/orders",
actionLabel: "عرض الطلب"
);
Raw / Custom Email Methods
// Simple plain-text or HTML email
await _mail.SendEmailAsync(
to: "user@example.com",
subject: "Test Subject",
body: "<h1>Hello World</h1>",
isHtml: true
);
// Templated email with {Placeholder} tokens in subject/body
await _mail.SendTemplatedEmailAsync(
to: "user@example.com",
subject: "مرحبا {UserName}",
templateBody: "<p>رمزك هو {Code}</p>",
placeholders: new Dictionary<string, string>
{
["UserName"] = "name",
["Code"] = "123456"
}
);
// Full control via EmailMessage object
var message = new EmailMessage
{
To = new List<string> { "user@example.com" },
Cc = new List<string> { "manager@example.com" },
Subject = "Full Control Email",
Body = "<p>Body here</p>",
IsBodyHtml = true,
Attachments = new List<EmailAttachment>
{
new EmailAttachment("report.pdf", pdfBytes, "application/pdf")
}
};
await _mail.SendEmailAsync(message);
IMailQueue — Fire-and-Forget API
Inject IMailQueue to enqueue emails without blocking the caller. A background hosted service delivers them automatically.
// All built-in templates are available as Enqueue* methods
_queue.EnqueueWelcome("user@example.com", "الاسم");
_queue.EnqueueOtp("user@example.com", "الاسم", "485921", expiryMinutes: 10);
_queue.EnqueueResetPassword("user@example.com", "الاسم", "https://example.com/reset");
_queue.EnqueueCreatePassword("user@example.com", "الاسم", "https://example.com/create");
_queue.EnqueueNotification("user@example.com", "الاسم", "عنوان", "نص الإشعار");
// Or enqueue a raw email message
_queue.Enqueue("user@example.com", "Subject", "<p>Body</p>", isHtml: true);
// Or enqueue a fully built EmailMessage
_queue.Enqueue(myEmailMessage);
EmailBuilder — Fluent API
Use EmailBuilder to construct complex messages without managing object initialization:
using Nasps.MailSender.Package.Builders;
using Nasps.MailSender.Package.Models;
EmailMessage message = EmailBuilder.Create()
.To("recipient@example.com")
.To("another@example.com")
.Cc("manager@example.com")
.From("noreply@example.com", "Nasps System")
.Subject("طلبك رقم {OrderNumber} تم الموافقة عليه")
.HtmlBody("<p>عزيزي {UserName}، تمت الموافقة على طلبك.</p>")
.WithPlaceholder("UserName", "الاسم")
.WithPlaceholder("OrderNumber", "ORD-9821")
.Attach("invoice.pdf", pdfBytes, "application/pdf")
.Build(); // throws InvalidOperationException if To or Subject is missing
await _mail.SendEmailAsync(message);
// or: _queue.Enqueue(message);
Configuration Reference
SmtpSettings
| Key | Type | Default | Description |
|---|---|---|---|
Host |
string | — | SMTP server hostname |
Port |
int | 587 |
465 = SSL, 587 = STARTTLS, 25 = plain |
EnableSsl |
bool | true |
Enables SSL/TLS |
UserName |
string | — | SMTP authentication username |
Password |
string | — | SMTP authentication password (use App Password for Gmail/Office365) |
FromEmail |
string | — | Default sender email address |
FromName |
string | — | Default sender display name |
UseDefaultCredentials |
bool | false |
Use Windows default credentials |
TimeoutMilliseconds |
int | 100000 |
Connection timeout |
RetryCount |
int | 3 |
Auto-retry attempts on failure (0 = disabled) |
RetryDelaySeconds |
int | 2 |
Seconds between retries |
QueueCapacity |
int | 500 |
Max emails in background queue |
EmailTemplateSettings
| Key | Description |
|---|---|
ProjectName |
Arabic project name shown in email header |
ProjectSubtitle |
Subtitle shown below the header |
SupportEmail |
Support email shown in the footer |
LogoUrl |
Hosted URL for your logo image (leave empty to hide) |
PrimaryColor |
Header gradient start color (hex, default #0d6efd) |
PrimaryColorDark |
Header gradient end color (hex, default #0a58ca) |
AccentColor |
Button / divider accent color (hex, default #4caf3a) |
AccentColorDark |
Accent darker shade (hex, default #2e7d23) |
FooterText |
Arabic copyright text |
CompanyName |
Company name in the footer |
WebsiteUrl |
Website URL linked in the footer |
Handling Results
ISmtpMailService methods return EmailResult:
var result = await _mail.SendWelcomeEmailAsync(to, userName);
if (result.IsSuccess)
{
// Email sent successfully
}
else
{
// Log the error
Console.WriteLine(result.ErrorMessage);
Console.WriteLine(result.Exception?.Message);
}
Note:
IMailQueuemethods are void — they are fire-and-forget. Failures are logged automatically by the background service using the standardILogger.
SMTP Provider Notes
Gmail
Google requires an App Password when 2-Step Verification is enabled.
- Go to Google Account → Security → App Passwords.
- Generate a new App Password and use it as your
Passwordsetting. - Use
Port: 587withEnableSsl: true.
Office 365 / Outlook
- Enable SMTP AUTH for the user in Microsoft 365 Admin Center → Users → Active Users → Mail → Manage email apps.
- If MFA is enabled, generate an App Password from the account security settings.
- Use
Host: smtp.office365.com,Port: 587.
Publishing a New Version
# 1. Pack
dotnet pack Nasps.MailSender.Package.csproj -c Release
# 2. Navigate to output
cd bin\Release
# 3. Push
dotnet nuget push Nasps.MailSender.Package.X.X.X.nupkg --api-key YOUR_KEY --source https://api.nuget.org/v3/index.json
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- MailKit (>= 4.16.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Polly (>= 8.6.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.