TwoRivers.Emailing
1.1.6
See the version list below for details.
dotnet add package TwoRivers.Emailing --version 1.1.6
NuGet\Install-Package TwoRivers.Emailing -Version 1.1.6
<PackageReference Include="TwoRivers.Emailing" Version="1.1.6" />
<PackageVersion Include="TwoRivers.Emailing" Version="1.1.6" />
<PackageReference Include="TwoRivers.Emailing" />
paket add TwoRivers.Emailing --version 1.1.6
#r "nuget: TwoRivers.Emailing, 1.1.6"
#:package TwoRivers.Emailing@1.1.6
#addin nuget:?package=TwoRivers.Emailing&version=1.1.6
#tool nuget:?package=TwoRivers.Emailing&version=1.1.6
TwoRivers.Emailing
Provides strongly-typed Email and EmailAddress value objects, email validation, and a fluent MailMessageBuilder for composing emails. Defines an IEmailSender interface for sending email messages. Designed to be used with dependency injection and can be easily mocked for testing.
Installation
You can install the TwoRivers.Emailing package via NuGet Package Manager Console:
Install-Package TwoRivers.Emailing
Or via .NET CLI:
dotnet add package TwoRivers.Emailing
Features
Value Objects
- Email: Strongly-typed email address value object
- EmailAddress: Combines display name and email address (compatible with
System.Net.Mail.MailAddress)
Email Validation
Multiple validation strategies:
- MailAddressEmailValidator: Uses .NET's built-in
MailAddressparsing - W3CEmailValidator: Validates against W3C email specification
- StrictEmailValidator: Strict validation with additional rules
- PatternEmailValidator: Regex-based validation
- ParsingEmailValidator: Configurable parsing validator
MailMessageBuilder
Fluent API for building email messages with:
- Markdown-to-HTML rendering
- Multiple recipients (To, CC, BCC)
- Priority and importance settings
- Attachments
- Plain text and HTML bodies
- Integration with
ClaimsPrincipalfor user emails
FluentValidation Integration
- EmailAddressPropertyValidator: Validates email properties in FluentValidation rules
Usage
Using MailMessageBuilder (Recommended)
using TwoRivers.Emailing;
public class EmailService
{
private readonly MailMessageBuilder _builder;
private readonly IEmailSender _sender;
public EmailService(MailMessageBuilder builder, IEmailSender sender)
{
_builder = builder;
_sender = sender;
}
public async Task SendWelcomeEmailAsync(ClaimsPrincipal user)
{
var message = _builder
.SendFrom("Support", "support@example.com")
.To(user) // Automatically extracts name and email from claims
.WithSubject("Welcome!")
.WithPriority(MailPriority.High)
.AppendLine("# Welcome to Our Service")
.AppendLine()
.AppendLine("We are excited to have you on board!")
.AppendLine()
.Append("Get started by visiting your [dashboard](https://example.com/dashboard).")
.Build();
await _sender.SendAsync(message);
}
}
Implementing IEmailSender
To use the TwoRivers.Emailing package, create an implementation of the IEmailSender interface to send emails. Here's an example using SMTP:
using System.Net.Mail;
using TwoRivers.Emailing;
public class SmtpEmailSender : IEmailSender
{
private readonly SmtpClient _smtpClient;
public SmtpEmailSender(SmtpClient smtpClient)
{
_smtpClient = smtpClient;
}
public async Task SendAsync(MailMessage message, CancellationToken cancellationToken = default)
{
await _smtpClient.SendMailAsync(message, cancellationToken);
}
}
Email Validation
using TwoRivers.Emailing;
public class RegistrationService
{
private readonly IEmailValidator _validator;
public RegistrationService(IEmailValidator validator)
{
_validator = validator;
}
public Boolean IsValidEmail(String email)
{
return _validator.IsValid(email);
}
}
Dependency Injection Setup
using Microsoft.Extensions.DependencyInjection;
using TwoRivers.Emailing;
// Configure email options
services.Configure<EmailOptions>(options =>
{
options.DefaultFromAddress = "noreply@example.com";
options.DefaultFromName = "Example Service";
});
// Register validators
services.AddSingleton<IEmailValidator, W3CEmailValidator>();
// Register builder (scoped for per-request isolation)
services.AddScoped<MailMessageBuilder>();
// Register email sender
services.AddSingleton<IEmailSender, SmtpEmailSender>();
// Configure SMTP client
services.AddSingleton<SmtpClient>(sp => new SmtpClient
{
Host = "smtp.example.com",
Port = 587,
EnableSsl = true,
Credentials = new NetworkCredential("username", "password")
});
FluentValidation Integration
using FluentValidation;
using TwoRivers.Emailing;
public class UserRegistrationRequest
{
public String Email { get; set; }
public String Name { get; set; }
}
public class UserRegistrationValidator : AbstractValidator<UserRegistrationRequest>
{
public UserRegistrationValidator()
{
RuleFor(x => x.Email)
.NotEmpty()
.SetValidator(new EmailAddressPropertyValidator());
}
}
Best Practices
Use MailMessageBuilder
The MailMessageBuilder provides a fluent API and handles common tasks like markdown rendering:
// Good - fluent and readable
var message = builder
.To("John Doe", "john@example.com")
.WithSubject("Invoice #12345")
.AppendLine("## Invoice Details")
.Build();
// Avoid - manual construction
var message = new MailMessage();
message.To.Add(new MailAddress("john@example.com", "John Doe"));
message.Subject = "Invoice #12345";
message.Body = "<h2>Invoice Details</h2>";
message.IsBodyHtml = true;
Leverage Value Objects
Use Email and EmailAddress types instead of strings:
// Good - strongly typed
public void SendNotification(EmailAddress recipient)
{
// Type safety ensures valid email addresses
}
// Avoid - stringly typed
public void SendNotification(String recipient)
{
// No compile-time guarantee of validity
}
Choose the Right Validator
Different validators for different needs:
// Strict validation for user registration
services.AddSingleton<IEmailValidator, StrictEmailValidator>();
// Lenient validation for email imports
services.AddSingleton<IEmailValidator, MailAddressEmailValidator>();
// W3C-compliant validation
services.AddSingleton<IEmailValidator, W3CEmailValidator>();
License
This project is licensed under the MIT License. See the LICENSE file for details.
| 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 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. |
-
net10.0
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.3)
- Microsoft.Extensions.Options (>= 10.0.3)
- TwoRivers.Security (>= 1.1.6)
-
net8.0
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.2)
- TwoRivers.Security (>= 1.1.6)
-
net9.0
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.0)
- TwoRivers.Security (>= 1.1.6)
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.0-beta.8 | 72 | 3/5/2026 |
| 2.0.0-beta.7 | 63 | 3/5/2026 |
| 2.0.0-beta.6 | 62 | 3/5/2026 |
| 2.0.0-beta.5 | 60 | 3/4/2026 |
| 2.0.0-beta.4 | 61 | 3/4/2026 |
| 2.0.0-beta.3 | 59 | 3/3/2026 |
| 2.0.0-beta.2 | 71 | 3/3/2026 |
| 2.0.0-beta.1 | 59 | 3/3/2026 |
| 2.0.0-beta.0 | 67 | 3/3/2026 |
| 1.1.6 | 118 | 2/26/2026 |
| 1.1.5 | 105 | 2/25/2026 |
| 1.1.4 | 107 | 2/22/2026 |
| 1.1.3 | 108 | 2/22/2026 |
| 1.1.2 | 109 | 2/22/2026 |
| 1.1.1 | 117 | 2/22/2026 |
| 1.1.0 | 113 | 2/22/2026 |
| 1.0.0 | 140 | 2/17/2026 |