Package icon

Noundry.Sanquhar.Mailgun 1.0.0

by Noundry

Noundry.Sanquhar

A flexible and powerful mailing library for .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.

.NET 8.0

.NET 9.0

.NET 10.0

No packages depend on Noundry.Sanquhar.Mailgun.

Initial release v1.0.0 - Mailgun integration using native HttpClient with IHttpClientFactory pattern.

Version Downloads Last Updated
1.0.0 Current 10 12/30/2025

Info

Statistics

Total Downloads
10
Current Version Downloads
10

Authors

Noundry