Fingent-SMTP-Email 1.0.2

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

Fingent SMTP Email

A simple and extensible SMTP email helper library for .NET applications. Streamlines sending emails by providing easy-to-use helper classes that wrap the .NET SmtpClient and related APIs. It supports common scenarios like sending plain text and HTML emails, attachments, and templated messages.

?? Features

  • SMTP Integration: Easy-to-use SMTP client wrapper for reliable email delivery
  • Multiple Formats: Support for plain text, HTML, and rich content emails
  • Attachment Support: Send files, documents, and embedded resources
  • Template Integration: Seamless integration with email templates
  • Async Support: Full async/await pattern for non-blocking operations
  • Configuration Management: Flexible SMTP server configuration
  • Error Handling: Comprehensive error handling and retry mechanisms
  • Security: SSL/TLS support for secure email transmission

?? Installation

dotnet add package Fingent-SMTP-Email

?? Dependencies

  • .NET 8.0
  • Microsoft.Extensions.DependencyInjection.Abstractions 8.0.1
  • Microsoft.Extensions.Logging.Abstractions 8.0.1
  • Microsoft.Extensions.Options 8.0.2

?? Usage

Basic Setup

// Program.cs or Startup.cs
services.AddSmtpEmail(options =>
{
    options.Host = "smtp.gmail.com";
    options.Port = 587;
    options.EnableSsl = true;
    options.Username = "your-email@gmail.com";
    options.Password = "your-password";
    options.From = "your-email@gmail.com";
    options.DisplayName = "Your Application Name";
});

Configuration

{
  "SmtpSettings": {
    "Host": "smtp.gmail.com",
    "Port": 587,
    "EnableSsl": true,
    "Username": "your-email@gmail.com",
    "Password": "your-app-password",
    "From": "your-email@gmail.com",
    "DisplayName": "Your Application Name",
    "Timeout": 30000
  }
}
// Using configuration
services.Configure<SmtpSettings>(configuration.GetSection("SmtpSettings"));
services.AddSmtpEmail();

Simple Email Sending

public class EmailService
{
    private readonly ISmtpEmailSender _emailSender;
    private readonly ILogger<EmailService> _logger;
    
    public EmailService(ISmtpEmailSender emailSender, ILogger<EmailService> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }
    
    public async Task SendWelcomeEmailAsync(string toEmail, string userName)
    {
        var email = new EmailMessage
        {
            To = new[] { toEmail },
            Subject = "Welcome to Our Application!",
            Body = $"Hello {userName}, welcome to our application!",
            IsHtml = false
        };
        
        await _emailSender.SendAsync(email);
        _logger.LogInformation("Welcome email sent to {Email}", toEmail);
    }
}

HTML Email with Styling

public class HtmlEmailService
{
    private readonly ISmtpEmailSender _emailSender;
    
    public HtmlEmailService(ISmtpEmailSender emailSender)
    {
        _emailSender = emailSender;
    }
    
    public async Task SendHtmlEmailAsync(string toEmail, string subject, string htmlContent)
    {
        var email = new EmailMessage
        {
            To = new[] { toEmail },
            Subject = subject,
            Body = htmlContent,
            IsHtml = true
        };
        
        await _emailSender.SendAsync(email);
    }
    
    public async Task SendRichWelcomeEmailAsync(string toEmail, string userName)
    {
        var htmlBody = $@"
            <!DOCTYPE html>
            <html>
            <head>
                <style>
                    body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; }}
                    .header {{ background-color: #4CAF50; color: white; padding: 20px; text-align: center; }}
                    .content {{ padding: 20px; background-color: #f9f9f9; }}
                    .footer {{ padding: 10px; text-align: center; background-color: #ddd; }}
                </style>
            </head>
            <body>
                <div class='header'>
                    <h1>Welcome to Our Platform!</h1>
                </div>
                <div class='content'>
                    <h2>Hello {userName}!</h2>
                    <p>Thank you for joining our platform. We're excited to have you on board.</p>
                    <p>Get started by exploring our features and setting up your profile.</p>
                </div>
                <div class='footer'>
                    <p>&copy; 2025 Your Company Name. All rights reserved.</p>
                </div>
            </body>
            </html>";
        
        await SendHtmlEmailAsync(toEmail, "Welcome to Our Platform!", htmlBody);
    }
}

Email with Attachments

public class AttachmentEmailService
{
    private readonly ISmtpEmailSender _emailSender;
    
    public AttachmentEmailService(ISmtpEmailSender emailSender)
    {
        _emailSender = emailSender;
    }
    
    public async Task SendEmailWithAttachmentAsync(string toEmail, string filePath, string fileName)
    {
        var email = new EmailMessage
        {
            To = new[] { toEmail },
            Subject = "Document Attached",
            Body = "Please find the attached document.",
            IsHtml = false,
            Attachments = new[]
            {
                new EmailAttachment
                {
                    FilePath = filePath,
                    FileName = fileName,
                    ContentType = "application/pdf"
                }
            }
        };
        
        await _emailSender.SendAsync(email);
    }
    
    public async Task SendEmailWithMultipleAttachmentsAsync(string toEmail, List<(string FilePath, string FileName)> attachments)
    {
        var emailAttachments = attachments.Select(a => new EmailAttachment
        {
            FilePath = a.FilePath,
            FileName = a.FileName,
            ContentType = GetContentType(a.FileName)
        }).ToArray();
        
        var email = new EmailMessage
        {
            To = new[] { toEmail },
            Subject = "Multiple Documents Attached",
            Body = "Please find the attached documents.",
            IsHtml = false,
            Attachments = emailAttachments
        };
        
        await _emailSender.SendAsync(email);
    }
    
    private string GetContentType(string fileName)
    {
        var extension = Path.GetExtension(fileName).ToLower();
        return extension switch
        {
            ".pdf" => "application/pdf",
            ".doc" => "application/msword",
            ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            ".xls" => "application/vnd.ms-excel",
            ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            ".jpg" or ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".gif" => "image/gif",
            ".txt" => "text/plain",
            _ => "application/octet-stream"
        };
    }
}

Bulk Email Sending

public class BulkEmailService
{
    private readonly ISmtpEmailSender _emailSender;
    private readonly ILogger<BulkEmailService> _logger;
    
    public BulkEmailService(ISmtpEmailSender emailSender, ILogger<BulkEmailService> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }
    
    public async Task SendBulkEmailAsync(List<string> recipients, string subject, string body, bool isHtml = false)
    {
        var batchSize = 50; // Send in batches to avoid overwhelming the SMTP server
        var batches = recipients.Chunk(batchSize);
        
        foreach (var batch in batches)
        {
            var tasks = batch.Select(async email =>
            {
                try
                {
                    var emailMessage = new EmailMessage
                    {
                        To = new[] { email },
                        Subject = subject,
                        Body = body,
                        IsHtml = isHtml
                    };
                    
                    await _emailSender.SendAsync(emailMessage);
                    _logger.LogInformation("Email sent successfully to {Email}", email);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to send email to {Email}", email);
                }
            });
            
            await Task.WhenAll(tasks);
            
            // Add delay between batches to avoid rate limiting
            await Task.Delay(1000);
        }
    }
    
    public async Task SendPersonalizedBulkEmailAsync(Dictionary<string, string> recipientData, string subjectTemplate, string bodyTemplate, bool isHtml = false)
    {
        var tasks = recipientData.Select(async kvp =>
        {
            try
            {
                var personalizedSubject = subjectTemplate.Replace("{Name}", kvp.Value);
                var personalizedBody = bodyTemplate.Replace("{Name}", kvp.Value);
                
                var emailMessage = new EmailMessage
                {
                    To = new[] { kvp.Key },
                    Subject = personalizedSubject,
                    Body = personalizedBody,
                    IsHtml = isHtml
                };
                
                await _emailSender.SendAsync(emailMessage);
                _logger.LogInformation("Personalized email sent to {Email}", kvp.Key);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to send personalized email to {Email}", kvp.Key);
            }
        });
        
        await Task.WhenAll(tasks);
    }
}

Email with Embedded Images

public class EmbeddedImageEmailService
{
    private readonly ISmtpEmailSender _emailSender;
    
    public EmbeddedImageEmailService(ISmtpEmailSender emailSender)
    {
        _emailSender = emailSender;
    }
    
    public async Task SendEmailWithEmbeddedImageAsync(string toEmail, string imagePath)
    {
        var htmlBody = @"
            <html>
            <body>
                <h2>Email with Embedded Image</h2>
                <p>Please see the image below:</p>
                <img src='cid:embedded-image' alt='Embedded Image' style='max-width: 400px;' />
                <p>Thank you!</p>
            </body>
            </html>";
        
        var email = new EmailMessage
        {
            To = new[] { toEmail },
            Subject = "Email with Embedded Image",
            Body = htmlBody,
            IsHtml = true,
            EmbeddedResources = new[]
            {
                new EmbeddedResource
                {
                    ContentId = "embedded-image",
                    FilePath = imagePath,
                    ContentType = "image/jpeg"
                }
            }
        };
        
        await _emailSender.SendAsync(email);
    }
}

Error Handling and Retry Logic

public class ReliableEmailService
{
    private readonly ISmtpEmailSender _emailSender;
    private readonly ILogger<ReliableEmailService> _logger;
    
    public ReliableEmailService(ISmtpEmailSender emailSender, ILogger<ReliableEmailService> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }
    
    public async Task<bool> SendEmailWithRetryAsync(EmailMessage email, int maxRetries = 3, int delayMs = 1000)
    {
        for (int attempt = 1; attempt <= maxRetries; attempt++)
        {
            try
            {
                await _emailSender.SendAsync(email);
                _logger.LogInformation("Email sent successfully on attempt {Attempt}", attempt);
                return true;
            }
            catch (SmtpException ex) when (attempt < maxRetries)
            {
                _logger.LogWarning(ex, "SMTP error on attempt {Attempt}/{MaxRetries}. Retrying in {Delay}ms", 
                    attempt, maxRetries, delayMs);
                await Task.Delay(delayMs);
                delayMs *= 2; // Exponential backoff
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to send email on attempt {Attempt}/{MaxRetries}", attempt, maxRetries);
                if (attempt == maxRetries)
                {
                    throw;
                }
                await Task.Delay(delayMs);
            }
        }
        
        return false;
    }
}

Email Queue Service

public class EmailQueueService
{
    private readonly ISmtpEmailSender _emailSender;
    private readonly ILogger<EmailQueueService> _logger;
    private readonly ConcurrentQueue<EmailMessage> _emailQueue = new();
    private readonly SemaphoreSlim _processingLock = new(1, 1);
    
    public EmailQueueService(ISmtpEmailSender emailSender, ILogger<EmailQueueService> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }
    
    public void QueueEmail(EmailMessage email)
    {
        _emailQueue.Enqueue(email);
        _logger.LogInformation("Email queued. Queue size: {QueueSize}", _emailQueue.Count);
        
        // Process queue in background
        _ = Task.Run(ProcessQueueAsync);
    }
    
    private async Task ProcessQueueAsync()
    {
        if (!await _processingLock.WaitAsync(100))
        {
            return; // Another process is already running
        }
        
        try
        {
            while (_emailQueue.TryDequeue(out var email))
            {
                try
                {
                    await _emailSender.SendAsync(email);
                    _logger.LogInformation("Queued email sent successfully");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to send queued email");
                    // Could implement dead letter queue here
                }
                
                await Task.Delay(500); // Rate limiting
            }
        }
        finally
        {
            _processingLock.Release();
        }
    }
}

?? Configuration Options

SMTP Settings

public class SmtpSettings
{
    public string Host { get; set; }
    public int Port { get; set; } = 587;
    public bool EnableSsl { get; set; } = true;
    public string Username { get; set; }
    public string Password { get; set; }
    public string From { get; set; }
    public string DisplayName { get; set; }
    public int Timeout { get; set; } = 30000;
    public bool UseDefaultCredentials { get; set; } = false;
}

Email Message Model

public class EmailMessage
{
    public string[] To { get; set; }
    public string[] Cc { get; set; }
    public string[] Bcc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public bool IsHtml { get; set; } = false;
    public EmailAttachment[] Attachments { get; set; }
    public EmbeddedResource[] EmbeddedResources { get; set; }
    public Dictionary<string, string> Headers { get; set; }
}

??? Architecture

The SMTP email system provides:

  • Reliable Delivery: Robust SMTP client implementation with error handling
  • Flexible Configuration: Support for various SMTP providers
  • Performance: Async operations and connection pooling
  • Security: SSL/TLS encryption and secure authentication
  • Scalability: Queue-based processing for high-volume scenarios

????? Author

Frebin Francis
Fingent Technology Solutions Pvt Ltd

?? License

Copyright � 2025 Fingent Technology Solutions Pvt Ltd

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 (1)

Showing the top 1 NuGet packages that depend on Fingent-SMTP-Email:

Package Downloads
Fingent-Logging-Serilog

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 208 9/24/2025