Noundry.Sanquhar 1.0.1

dotnet add package Noundry.Sanquhar --version 1.0.1
                    
NuGet\Install-Package Noundry.Sanquhar -Version 1.0.1
                    
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="Noundry.Sanquhar" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Noundry.Sanquhar" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Noundry.Sanquhar" />
                    
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 Noundry.Sanquhar --version 1.0.1
                    
#r "nuget: Noundry.Sanquhar, 1.0.1"
                    
#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 Noundry.Sanquhar@1.0.1
                    
#: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=Noundry.Sanquhar&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Noundry.Sanquhar&version=1.0.1
                    
Install as a Cake Tool

Noundry.Sanquhar

A flexible and powerful mailing library for .NET 8.0, .NET 9.0, and .NET 10.0 applications that separates email template rendering from email sending, allowing developers to easily create and send emails with dynamic content.

Features

  • Template Rendering: Render email templates using Razor syntax with model data binding
  • Multiple Sending Providers: Support for SMTP, SendGrid, and Mailgun
  • Email Validation: Built-in email address validation
  • Template Caching: Improve performance with automatic template caching
  • Dependency Injection: Full DI support for easy integration into ASP.NET Core applications
  • Comprehensive Logging: Built-in logging using Microsoft.Extensions.Logging
  • Attachments: Support for email attachments
  • HTML & Plain Text: Send multipart emails with both HTML and plain text versions
  • Custom Headers: Add custom email headers
  • Priority Support: Set email priority levels (Low, Normal, High)

Installation

Install the base package:

dotnet add package Noundry.Sanquhar

For SendGrid support:

dotnet add package Noundry.Sanquhar.SendGrid

For Mailgun support:

dotnet add package Noundry.Sanquhar.Mailgun

Quick Start

1. Configure in appsettings.json

{
  "Sanquhar": {
    "TemplatePath": "EmailTemplates",
    "EnableTemplateCache": true,
    "TemplateCacheExpirationMinutes": 60,
    "Smtp": {
      "Host": "smtp.example.com",
      "Port": 587,
      "Username": "user@example.com",
      "Password": "your-password",
      "EnableSsl": true
    },
    "Mail": {
      "DefaultFrom": "noreply@example.com",
      "DefaultFromName": "My Application",
      "DefaultReplyTo": "support@example.com",
      "EnableEmailValidation": true
    }
  }
}

2. Register Services in Program.cs

Using SMTP:

using Noundry.Sanquhar.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add Sanquhar with SMTP
builder.Services.AddSanquhar(builder.Configuration);

var app = builder.Build();
app.Run();

Using SendGrid:

using Noundry.Sanquhar.Extensions;
using Noundry.Sanquhar.SendGrid.Extensions;

builder.Services.AddSanquhar(builder.Configuration, options =>
    options.UseSendGrid(builder.Configuration));

Using Mailgun:

using Noundry.Sanquhar.Extensions;
using Noundry.Sanquhar.Mailgun.Extensions;

builder.Services.AddSanquhar(builder.Configuration, options =>
    options.UseMailgun(builder.Configuration));

3. Create Email Templates

Create a directory named EmailTemplates in your project root.

Welcome.cshtml (HTML body):

@model WelcomeEmailModel

<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>Welcome, @Model.Username!</h1>
    <p>Thank you for joining on @Model.RegistrationDate.ToString("D").</p>
</body>
</html>

Welcome_Subject.cshtml (Subject line):

@model WelcomeEmailModel
Welcome to Our Service, @Model.Username!

Welcome_Text.cshtml (Optional plain text version):

@model WelcomeEmailModel

Hello, @Model.Username!
Thank you for joining on @Model.RegistrationDate.ToString("D").

4. Send Emails

From a Controller or Service:

using Noundry.Sanquhar.Services;

public class UserService
{
    private readonly IMailService _mailService;

    public UserService(IMailService mailService)
    {
        _mailService = mailService;
    }

    public async Task SendWelcomeEmail(string email, string username)
    {
        var model = new WelcomeEmailModel
        {
            Username = username,
            RegistrationDate = DateTime.Now
        };

        // Create email from template
        var message = await _mailService.CreateFromTemplateAsync("Welcome", model);
        message.To.Add(email);

        // Send email
        await _mailService.SendAsync(message);
    }

    // OR use shorthand method
    public async Task SendWelcomeEmailShorthand(string email, string username)
    {
        var model = new WelcomeEmailModel
        {
            Username = username,
            RegistrationDate = DateTime.Now
        };

        await _mailService.SendFromTemplateAsync("Welcome", model, email);
    }
}

public class WelcomeEmailModel
{
    public string Username { get; set; }
    public DateTime RegistrationDate { get; set; }
}

Sending without Templates:

using Noundry.Sanquhar.Models;
using Noundry.Sanquhar.Services;

public class NotificationService
{
    private readonly IMailService _mailService;

    public NotificationService(IMailService mailService)
    {
        _mailService = mailService;
    }

    public async Task SendSimpleEmail(string to, string subject, string body)
    {
        var message = new MailMessage
        {
            Subject = subject,
            HtmlBody = $"<html><body>{body}</body></html>",
            Body = body
        };

        message.To.Add(to);

        await _mailService.SendAsync(message);
    }
}

Configuration Options

Sanquhar Options

Property Type Default Description
TemplatePath string "EmailTemplates" Directory containing email templates
EnableTemplateCache bool true Enable template caching for performance
TemplateCacheExpirationMinutes int 60 Template cache expiration time in minutes

SMTP Settings

Property Type Default Description
Host string - SMTP server hostname
Port int 587 SMTP server port
Username string - SMTP authentication username
Password string - SMTP authentication password
EnableSsl bool true Enable SSL/TLS
Timeout int 10000 Connection timeout in milliseconds

SendGrid Settings

Add to appsettings.json:

{
  "Sanquhar": {
    "SendGrid": {
      "ApiKey": "your-sendgrid-api-key",
      "EnableClickTracking": true,
      "EnableOpenTracking": true,
      "SandboxMode": false
    }
  }
}

Mailgun Settings

Add to appsettings.json:

{
  "Sanquhar": {
    "Mailgun": {
      "ApiKey": "your-mailgun-api-key",
      "Domain": "your-domain.mailgun.org",
      "ApiBaseUrl": "https://api.mailgun.net/v3",
      "EnableTracking": true,
      "EnableClickTracking": true,
      "EnableOpenTracking": true
    }
  }
}

Mail Settings

Property Type Default Description
DefaultFrom string - Default sender email address
DefaultFromName string null Default sender display name
DefaultReplyTo string null Default reply-to email address
EnableEmailValidation bool true Enable email address validation

Advanced Usage

Adding Attachments

var message = await _mailService.CreateFromTemplateAsync("Invoice", model);
message.To.Add(customer.Email);

// Add attachment
message.Attachments.Add(new MailAttachment
{
    FileName = "invoice.pdf",
    Content = pdfBytes,
    ContentType = "application/pdf"
});

await _mailService.SendAsync(message);

Setting Priority

var message = new MailMessage
{
    Subject = "Urgent: Action Required",
    HtmlBody = urgentMessageBody,
    Priority = MailPriority.High
};

message.To.Add(recipient);
await _mailService.SendAsync(message);

Adding CC and BCC Recipients

var message = await _mailService.CreateFromTemplateAsync("Notification", model);
message.To.Add("primary@example.com");
message.Cc.Add("manager@example.com");
message.Bcc.Add("admin@example.com");

await _mailService.SendAsync(message);

Custom Headers

var message = new MailMessage
{
    Subject = "Custom Email",
    HtmlBody = body
};

message.Headers.Add("X-Custom-Header", "CustomValue");
message.Headers.Add("X-Campaign-ID", campaignId);

message.To.Add(recipient);
await _mailService.SendAsync(message);

Template Naming Conventions

Sanquhar follows these naming conventions for templates:

  • [TemplateName].cshtml: Main HTML body template
  • [TemplateName]_Subject.cshtml: Subject line template
  • [TemplateName]_Text.cshtml: Plain text version (optional)

For example, for a "Welcome" email:

  • Welcome.cshtml - HTML body
  • Welcome_Subject.cshtml - Subject line
  • Welcome_Text.cshtml - Plain text version

Dependency Injection

Sanquhar registers the following services:

  • IMailService - High-level email service
  • IMailSender - Email sending implementation (SMTP, SendGrid, or Mailgun)
  • ITemplateRenderer - Template rendering engine
  • IEmailValidator - Email address validation

All services are registered as Scoped by default.

Logging

Sanquhar uses Microsoft.Extensions.Logging throughout. To see detailed logs, configure logging in appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Noundry.Sanquhar": "Debug"
    }
  }
}

Demo Application

The Demo project includes a complete working example with:

  • RESTful API endpoints for sending emails
  • Sample email templates
  • Configuration examples for all providers
  • Scalar UI for interactive API testing (modern .NET 9)

To run the demo:

cd Demo
dotnet run

Navigate to https://localhost:5001/scalar/v1 to explore the API with Scalar's beautiful UI.

Best Practices

  1. Use Templates: Leverage Razor templates for maintainable, reusable email content
  2. Enable Caching: Keep template caching enabled in production for better performance
  3. Email Validation: Keep email validation enabled to catch errors early
  4. Environment-Specific Configuration: Use different SMTP/API settings for development and production
  5. Logging: Configure appropriate log levels to monitor email delivery
  6. Error Handling: Always wrap email sending in try-catch blocks and handle failures gracefully
  7. Testing: Use sandbox mode for SendGrid or test SMTP servers during development

Troubleshooting

Templates Not Found

Ensure your template path is correct:

  • Check TemplatePath in appsettings.json
  • Verify template files exist in the specified directory
  • Ensure template files have .cshtml extension

SMTP Connection Errors

  • Verify SMTP host and port are correct
  • Check username and password
  • Ensure EnableSsl matches your SMTP server requirements
  • Check firewall settings

SendGrid/Mailgun API Errors

  • Verify API key is valid
  • Check API key has appropriate permissions
  • For Mailgun, ensure domain is correctly configured

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License.

Support

For issues, questions, or feature requests, please open an issue on GitHub.

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 is compatible.  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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Noundry.Sanquhar:

Package Downloads
Noundry.Sanquhar.SendGrid

SendGrid email provider integration for Noundry.Sanquhar mailing library. Send emails via SendGrid's API with click tracking, open tracking, and sandbox mode support. Requires Noundry.Sanquhar core library.

Noundry.Sanquhar.Mailgun

Mailgun email provider integration for Noundry.Sanquhar mailing library. Send emails via Mailgun's REST API using modern HttpClient with click tracking and open tracking support. Zero third-party HTTP dependencies. Requires Noundry.Sanquhar core library.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 142 3/4/2026

Initial release v1.0.0 - Production-ready mailing library with Razor templates, SMTP/SendGrid/Mailgun support, modern .NET 9 features, and comprehensive documentation.