Skip to content

GridLab Email Sending Service - Skills Guide

Skill Type: Communication & Messaging
Technology Stack: .NET, ABP Framework, SMTP
Complexity Level: Beginner
Last Updated: 2024


📋 Overview

The GridLab Email Service provides enterprise-grade email sending capabilities with SMTP integration, background job support, and comprehensive configuration options for ABP Framework applications.

Key Capabilities

  • ✅ Simple and intuitive IEmailSender service
  • ✅ Flexible SMTP configuration
  • ✅ Background job integration for async sending
  • ✅ Template-based email support
  • ✅ SSL/TLS encryption support
  • ✅ Multiple authentication methods

Prerequisites

  • .NET 9.0 or higher
  • SMTP server access (Gmail, SendGrid, etc.)
  • NuGet package manager

🚀 Quick Start

Step 1: Install NuGet Package

Install the GridLab.Abp.Emailing package from NuGet:

Install-Package GridLab.Abp.Emailing

Package Information:

Step 2: Add Module Dependency

Add the AbpGridLabEmailingModule to your ABP module's dependency list:

[DependsOn(
    //...other dependencies
    typeof(AbpGridLabEmailingModule)
)]
public class YourModule : AbpModule
{
}

Step 3: Configure Email Settings

Locate appsettings.json in your project and add email configuration:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Email": {
    "FromAddress": "noreply@gridlab.io",
    "FromDisplayName": "GridLab GMS²",
    "UserName": "noreply",
    "Password": "your-smtp-password",
    "Host": "smtp.gmail.com",
    "Port": 587,
    "EnableSsl": true
  },
  "AllowedHosts": "*"
}

⚙️ Configuration Reference

Email Options

Configure email options in your module's ConfigureServices method:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    var configuration = context.Services.GetConfiguration();

    Configure<EmailOptions>(options =>
    {
        options.FromAddress = configuration["Email:FromAddress"];
        options.FromDisplayName = configuration["Email:FromDisplayName"];
        options.UserName = configuration["Email:UserName"];
        options.Password = configuration["Email:Password"];
        options.Host = configuration["Email:Host"];
        options.Port = int.Parse(configuration["Email:Port"] ?? "587");
        options.EnableSsl = bool.Parse(configuration["Email:EnableSsl"] ?? "true");
        options.UseDefaultCredentials = false;
    });
}

Configuration Properties

Property Description Default Value Required
Host SMTP server hostname or IP address smtp.gmail.com ✅ Yes
Port SMTP server port number 587 ✅ Yes
UserName SMTP authentication username Empty ✅ Yes
Password SMTP authentication password Empty ✅ Yes
Domain Domain for SMTP authentication Empty ❌ No
EnableSsl Enable SSL/TLS encryption true 🟡 Recommended
UseDefaultCredentials Use Windows credentials false ❌ No
FromAddress Default sender email address Empty ✅ Yes
FromDisplayName Default sender display name GridLab GMS² ❌ No

💡 Usage Examples

Basic Email Sending

public class NotificationService : ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly ILogger<NotificationService> _logger;

    public NotificationService(
        IEmailSender emailSender,
        ILogger<NotificationService> logger)
    {
        _emailSender = emailSender;
        _logger = logger;
    }

    public async Task SendWelcomeEmailAsync(string userEmail, string userName)
    {
        try
        {
            await _emailSender.SendAsync(
                to: userEmail,
                subject: "Welcome to GridLab!",
                body: $"Hello {userName},<br><br>Welcome to our platform!<br><br>Best regards,<br>GridLab Team",
                isBodyHtml: true
            );

            _logger.LogInformation("Welcome email sent to {Email}", userEmail);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send welcome email to {Email}", userEmail);
            throw;
        }
    }
}

HTML Email with Template

public class TemplateEmailService : ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly ITemplateRenderer _templateRenderer;

    public TemplateEmailService(
        IEmailSender emailSender,
        ITemplateRenderer templateRenderer)
    {
        _emailSender = emailSender;
        _templateRenderer = templateRenderer;
    }

    public async Task SendPasswordResetEmailAsync(string email, string resetToken)
    {
        var model = new
        {
            ResetLink = $"https://yourapp.com/reset-password?token={resetToken}",
            ExpiryHours = 24
        };

        var body = await _templateRenderer.RenderAsync(
            "EmailTemplates/PasswordReset",
            model
        );

        await _emailSender.SendAsync(
            to: email,
            subject: "Password Reset Request",
            body: body,
            isBodyHtml: true
        );
    }
}

Batch Email Sending

public class BulkEmailService : ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly IBackgroundJobManager _backgroundJobManager;

    public BulkEmailService(
        IEmailSender emailSender,
        IBackgroundJobManager backgroundJobManager)
    {
        _emailSender = emailSender;
        _backgroundJobManager = backgroundJobManager;
    }

    public async Task SendNewsletterAsync(List<string> recipients, string content)
    {
        foreach (var recipient in recipients)
        {
            // Queue emails as background jobs for better performance
            await _backgroundJobManager.EnqueueAsync(
                new SendEmailArgs
                {
                    To = recipient,
                    Subject = "Monthly Newsletter",
                    Body = content,
                    IsBodyHtml = true
                }
            );
        }
    }
}

Email with Attachments

public class DocumentEmailService : ITransientDependency
{
    private readonly IEmailSender _emailSender;

    public DocumentEmailService(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    public async Task SendInvoiceEmailAsync(string email, byte[] pdfData, string invoiceNumber)
    {
        var message = new MailMessage
        {
            To = { email },
            Subject = $"Invoice #{invoiceNumber}",
            Body = $"Please find attached invoice #{invoiceNumber}.",
            IsBodyHtml = true
        };

        var attachment = new Attachment(
            new MemoryStream(pdfData),
            $"Invoice_{invoiceNumber}.pdf",
            "application/pdf"
        );

        message.Attachments.Add(attachment);

        await _emailSender.SendAsync(message);
    }
}

🔧 Advanced Scenarios

Background Job Integration

[DependsOn(typeof(AbpBackgroundJobsModule))]
public class YourModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpBackgroundJobOptions>(options =>
        {
            options.IsJobExecutionEnabled = true;
        });
    }
}

public class SendEmailJob : AsyncBackgroundJob<SendEmailArgs>, ITransientDependency
{
    private readonly IEmailSender _emailSender;

    public SendEmailJob(IEmailSender emailSender)
    {
        _emailSender = emailSender;
    }

    public override async Task ExecuteAsync(SendEmailArgs args)
    {
        await _emailSender.SendAsync(
            args.To,
            args.Subject,
            args.Body,
            args.IsBodyHtml
        );
    }
}

SMTP Provider Examples

Gmail Configuration

{
  "Email": {
    "Host": "smtp.gmail.com",
    "Port": 587,
    "EnableSsl": true,
    "UserName": "your-email@gmail.com",
    "Password": "your-app-specific-password"
  }
}

SendGrid Configuration

{
  "Email": {
    "Host": "smtp.sendgrid.net",
    "Port": 587,
    "EnableSsl": true,
    "UserName": "apikey",
    "Password": "your-sendgrid-api-key"
  }
}

Office 365 Configuration

{
  "Email": {
    "Host": "smtp.office365.com",
    "Port": 587,
    "EnableSsl": true,
    "UserName": "your-email@yourdomain.com",
    "Password": "your-password"
  }
}

📚 Best Practices

✅ Do's

  • Use environment variables for sensitive SMTP credentials
  • Enable SSL/TLS for secure transmission
  • Implement retry logic for failed email sends
  • Use background jobs for non-critical emails
  • Validate email addresses before sending
  • Log email sending activities

❌ Don'ts

  • Don't hardcode SMTP passwords in source code
  • Don't send emails synchronously in request handlers
  • Don't expose email addresses in logs
  • Don't send emails without user consent
  • Don't use production SMTP in development

🔍 Troubleshooting

Common Issues

Issue: SMTP authentication failed

  • Solution: Verify username and password are correct
  • Solution: For Gmail, use App-Specific Password instead of account password
  • Solution: Check if "Less secure app access" is enabled (if applicable)

Issue: Connection timeout

  • Solution: Verify SMTP host and port are correct
  • Solution: Check firewall settings
  • Solution: Ensure network connectivity to SMTP server

Issue: SSL/TLS errors

  • Solution: Verify EnableSsl is set to true for port 587
  • Solution: Check certificate validation settings

📖 Additional Resources