PrimusSaaS.Notifications 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package PrimusSaaS.Notifications --version 1.2.0
                    
NuGet\Install-Package PrimusSaaS.Notifications -Version 1.2.0
                    
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="PrimusSaaS.Notifications" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PrimusSaaS.Notifications" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="PrimusSaaS.Notifications" />
                    
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 PrimusSaaS.Notifications --version 1.2.0
                    
#r "nuget: PrimusSaaS.Notifications, 1.2.0"
                    
#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 PrimusSaaS.Notifications@1.2.0
                    
#: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=PrimusSaaS.Notifications&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=PrimusSaaS.Notifications&version=1.2.0
                    
Install as a Cake Tool

Primus.Notifications

Production-ready notification building blocks for Primus SaaS applications. The library provides SMTP email delivery, file-based templating with Fluid, an in-memory queue with a background worker, and instrumentation hooks for observability.

Features

  • SMTP email channel with retry/backoff and structured logging
  • File-based Liquid templates with caching and subject/body conventions
  • In-memory bounded queue plus background worker for async delivery
  • Lightweight diagnostics via NotificationMetrics and NotificationRuntimeStats
  • Opt-in logger channel for non-email scenarios or local development
  • NotificationResult surface that reports per-channel outcomes and can throw on failure to prevent silent drops

Installation

dotnet add package Primus.Notifications --version 1.2.0

Quick start (ASP.NET Core)

builder.Services.AddPrimusNotifications(notifications =>
{
    notifications
        .UseSmtp(opts =>
        {
            opts.Host = builder.Configuration["Smtp:Host"];
            opts.Port = 587;
            opts.Username = builder.Configuration["Smtp:Username"];
            opts.Password = builder.Configuration["Smtp:Password"];
            opts.FromAddress = "no-reply@primus.local";
            opts.FromName = "Primus Notifications";
            opts.EnableSsl = true;
        })
        .UseFileTemplates(Path.Combine(builder.Environment.ContentRootPath, "NotificationTemplates"))
        .UseInMemoryQueue(options =>
        {
            options.BoundedCapacity = 500;
            options.MaxParallelHandlers = 2;
        })
        .UseSms() // logs SMS payloads by default; swap ISmsSender for your provider
        .UseLogger();
});

Create a notification type:

public record WelcomeNotification(string Email, string Name) : INotification
{
    public string Type => "Welcome";
    public object Data => new { Name };
    public IEnumerable<string> Channels => new[] { "Email", "Logger" };
    public Recipient Recipient => new() { Email = Email, Name = Name };
}

Render templates from NotificationTemplates/Welcome/EmailSubject.liquid and NotificationTemplates/Welcome/EmailBody.liquid, then enqueue or send directly:

var notification = new WelcomeNotification("ada@example.com", "Ada");

// Async queue (recommended)
await queue.EnqueueAsync(notification, cancellationToken);

// Or immediate dispatch
var result = await notificationService.SendAsync(notification, cancellationToken);
if (!result.Success)
{
    // Log/return a 500 so the failure is visible
    logger.LogError("Notification failed: {Reason}", result.FailureReason);
}

Send one-off notifications without creating a custom INotification type:

await notificationService.SendEmailAsync("user@example.com", "Welcome", "<p>Thanks for signing up!</p>");
await notificationService.SendSmsAsync("+15551234567", "Your code is 123456");

Both helpers return NotificationResult and will throw NotificationFailedException when NotificationOptions.ThrowOnFailure is enabled (default) and nothing was delivered.

Plug in your SMS provider by implementing ISmsSender and registering it:

builder.Services.AddPrimusNotifications(notifications =>
{
    notifications.UseSms<MySmsSender>(); // replaces the default logging sender
});

Twilio SMS (Built-in)

The library includes a production-ready Twilio SMS sender. Configure it with your Twilio credentials:

Option 1: Inline configuration

builder.Services.AddPrimusNotifications(notifications =>
{
    notifications.UseTwilio(opts =>
    {
        opts.AccountSid = builder.Configuration["Twilio:AccountSid"];
        opts.AuthToken = builder.Configuration["Twilio:AuthToken"];
        opts.FromNumber = builder.Configuration["Twilio:FromNumber"];
    });
});

Option 2: From appsettings.json

builder.Services.AddPrimusNotifications(notifications =>
{
    notifications.UseTwilio(builder.Configuration);
});
{
  "Twilio": {
    "AccountSid": "your-account-sid",
    "AuthToken": "your-auth-token",
    "FromNumber": "+1234567890"
  }
}

Send SMS

await notificationService.SendSmsAsync("+15551234567", "Your verification code is 123456");

Environment variables (examples):

  • Twilio__AccountSid=ACxxxx
  • Twilio__AuthToken=...
  • Twilio__FromNumber=+16205538468

Notes: Twilio trial accounts require verifying each recipient number before sending. Keep AuthToken in secrets/Key Vault/env vars—never commit secrets. Twilio options are validated during startup (can be disabled with ValidateOnStartup = false).

SMTP configuration

SmtpOptions supports host, port, credentials, SSL, sender info, timeout, retry count, and exponential backoff base delay. Validation runs during DI configuration to catch missing host/port/from settings early.

Templates

  • File layout: {BasePath}/{NotificationType}/EmailSubject.liquid and EmailBody.liquid
  • SMS layout: {BasePath}/{NotificationType}/SmsBody.liquid (optional)
  • Fluid syntax with anonymous/POCO models
  • Templates are cached after first parse for performance
  • See TEMPLATE_GUIDE.md for conventions and examples

Direct helpers (SendEmailAsync(to, subject, body) / SendSmsAsync(phone, message)) skip template lookup entirely to avoid confusing failures when you just want to send raw content.

Background processing

Calling .UseInMemoryQueue() registers InMemoryNotificationQueue and NotificationBackgroundService to drain the queue using scoped NotificationService instances. Configure capacity, max parallel handlers, and retry/backoff per NotificationQueueOptions.

Diagnostics

Expose metrics via NotificationMetrics (System.Diagnostics.Metrics instruments) and quick in-process stats via NotificationRuntimeStats.GetSnapshot().

Building and packing

dotnet test sdk/dotnet/Primus.Notifications.Tests/Primus.Notifications.Tests.csproj
dotnet pack sdk/dotnet/Primus.Notifications/Primus.Notifications.csproj -c Release

Packages are emitted to nupkg/ with symbols and README included.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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
2.0.1 29 3/11/2026
2.0.0 156 1/12/2026
1.4.2 350 11/30/2025
1.4.1 489 11/30/2025
1.3.0 250 11/29/2025
1.2.0 136 11/29/2025
1.1.0 123 11/29/2025
1.0.0 123 11/28/2025

v1.2.0: NotificationResult with failure reasons, ThrowOnFailure option, template-less direct email/SMS helpers, startup Twilio validation, and multi-targeting for net6/net7/net8.