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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nasps.MailSender.Package" Version="1.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nasps.MailSender.Package" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Nasps.MailSender.Package" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nasps.MailSender.Package --version 1.1.2
                    
#r "nuget: Nasps.MailSender.Package, 1.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nasps.MailSender.Package@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nasps.MailSender.Package&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Nasps.MailSender.Package&version=1.1.2
                    
Install as a Cake Tool

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: IMailQueue methods are void — they are fire-and-forget. Failures are logged automatically by the background service using the standard ILogger.


SMTP Provider Notes

Gmail

Google requires an App Password when 2-Step Verification is enabled.

  1. Go to Google Account → Security → App Passwords.
  2. Generate a new App Password and use it as your Password setting.
  3. Use Port: 587 with EnableSsl: true.

Office 365 / Outlook

  1. Enable SMTP AUTH for the user in Microsoft 365 Admin Center → Users → Active Users → Mail → Manage email apps.
  2. If MFA is enabled, generate an App Password from the account security settings.
  3. 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1.2 112 8/31/2026
1.0.0 106 8/26/2026