Advanced Dispatcher Patterns
Offline storage, logging, multi-provider routing, IP pooling, blockchain ideas for custom providers.
Pattern 1: Offline Queue Dispatcher
Idea: Buffer failed emails to database, retry asynchronously.
public class OfflineQueueDispatcher : IEmailDispatcher
{
public async Task SendAsync(...)
{
try
{
// Try main dispatcher
return await _mainDispatcher.SendAsync(...);
}
catch
{
// Store in offline queue
await _offlineQueueService.EnqueueAsync(message, ct);
return EmailDispatchResult.Ok("queued");
}
}
} Pattern 2: Logging Dispatcher
Idea: Log all emails to database/file before sending. Audit trail.
public class LoggingDispatcher : IEmailDispatcher
{
public async Task SendAsync(...)
{
// Log email
await _auditLog.LogAsync(new EmailAuditLog {
TenantID=metadata.TenantID, To=message.To, Subject=message.Subject
}, ct);
// Send via main dispatcher
return await _mainDispatcher.SendAsync(...);
}
} Pattern 3: Multi-Provider Router
Idea: Route to different providers based on email type or cost.
public class MultiProviderRouter : IEmailDispatcher
{
public async Task SendAsync(...)
{
// Route based on subject/type
var provider = message.Subject.Contains("urgent") ? "ses" : "smtp";
var dispatcher = _factory.Get(provider);
return await dispatcher.SendAsync(...);
}
} Pattern 4: IP Pooling Dispatcher
Idea: Distribute emails across multiple SES sending pools for reputation management.
public class IPPoolingDispatcher : IEmailDispatcher
{
public async Task SendAsync(...)
{
// Select IP pool based on tenant/domain
var pool = _ipPoolSelector.Select(message.To);
var metadata = metadata with { IPPool = pool };
return await _sesDispatcher.SendAsync(credential, metadata, message, ct);
}
} Pattern 5: Blockchain-Enabled Dispatcher
Idea: Log email hashes to blockchain for compliance/audit.
public class BlockchainDispatcher : IEmailDispatcher
{
public async Task SendAsync(...)
{
// Send email
var result = await _mainDispatcher.SendAsync(...);
// Hash and log to blockchain
if (result.Success)
{
var hash = Hash(message.Html + result.MessageID);
await _blockchain.LogAsync(hash, ct);
}
return result;
}
} Pattern 6: Rate-Limited Dispatcher
Idea: Enforce per-tenant or per-recipient rate limits.
public class RateLimitedDispatcher : IEmailDispatcher
{
public async Task SendAsync(...)
{
// Check rate limit: 100 emails/minute per tenant
if (!await _rateLimiter.AllowAsync(metadata.TenantID, 100, 60, ct))
return EmailDispatchResult.Fail("RATE_LIMIT", "Quota exceeded");
return await _mainDispatcher.SendAsync(...);
}
} Next Steps
- Bring Your Own Provider — Implement custom dispatchers
- Sample JSON
