do not auto-add all mail-dispatchers; manual registration required from now on

This commit is contained in:
2026-04-29 13:04:58 +02:00
parent b7aa134c5a
commit 427757ef2f
9 changed files with 38 additions and 85 deletions
@@ -2,16 +2,6 @@
public interface IMailDispatcher : IDisposable
{
/// <summary>
/// If multiple dispatchers are available, the dispatcher with the highest priority will be used
/// </summary>
int Priority { get; }
/// <summary>
/// Whether this dispatcher is properly configured and can send mails
/// </summary>
bool CanSend();
/// <summary>
/// Sends a mail message
/// </summary>
@@ -9,13 +9,6 @@ namespace Finch.Mails.Dispatchers;
/// </summary>
public class LoggerMailDispatcher(ILogger<LoggerMailDispatcher> logger) : IMailDispatcher
{
/// <inheritdoc />
public int Priority { get; } = -10;
/// <inheritdoc />
public bool CanSend() => true;
/// <inheritdoc />
public Task Send(Mail message, CancellationToken token = default)
{
@@ -1,23 +0,0 @@
namespace Finch.Mails.Dispatchers;
public class MailDispatcherResolver(IEnumerable<IMailDispatcher> dispatchers) : IMailDispatcherResolver
{
/// <inheritdoc />
public Task<IMailDispatcher> Resolve()
{
IMailDispatcher dispatcher = dispatchers
.OrderByDescending(x => x.Priority)
.FirstOrDefault(dispatcher => dispatcher.CanSend());
return Task.FromResult(dispatcher);
}
}
public interface IMailDispatcherResolver
{
/// <summary>
/// Resolves a mail dispatcher to use for sending emails
/// </summary>
Task<IMailDispatcher> Resolve();
}
@@ -8,9 +8,6 @@ namespace Finch.Mails.Dispatchers.Postmark;
public class PostmarkDispatcher : IMailDispatcher
{
/// <inheritdoc />
public int Priority { get; } = 3;
protected PostmarkClient Postmark { get; set; }
protected PostmarkAdminClient PostmarkAdmin { get; set; }
@@ -36,13 +33,6 @@ public class PostmarkDispatcher : IMailDispatcher
}
/// <inheritdoc />
public bool CanSend()
{
return Options.Postmark != null && !Options.Postmark.ServerToken.IsNullOrEmpty();
}
/// <inheritdoc />
public async Task<bool> IsSenderSupported(string email)
{
@@ -13,9 +13,6 @@ namespace Finch.Mails.Dispatchers.Scaleway;
public class ScalewayDispatcher : IMailDispatcher
{
/// <inheritdoc />
public int Priority { get; } = 3;
protected Queue<Mail> Queue { get; } = new();
protected MailOptions Options { get; set; }
@@ -45,13 +42,6 @@ public class ScalewayDispatcher : IMailDispatcher
}
/// <inheritdoc />
public bool CanSend()
{
return Options.Scaleway != null && !Options.Scaleway.ProjectId.IsNullOrEmpty() && !Options.Scaleway.SecretKey.IsNullOrEmpty();
}
/// <inheritdoc />
public async Task<bool> IsSenderSupported(string email, CancellationToken token = default)
{
@@ -82,6 +72,8 @@ public class ScalewayDispatcher : IMailDispatcher
ScalewayRequest.SendEmail data = new()
{
ProjectId = Options.Scaleway.ProjectId,
// to addresses
To = Convert(message.To),
Cc = Convert(message.CC),
@@ -137,27 +129,18 @@ public class ScalewayDispatcher : IMailDispatcher
data.Html = message.Body;
}
// overwrite for debug mode
if (Options.Debug || (Env != null && !Env.IsProduction()))
{
data.From = new ScalewayRequest.EmailAddress()
{
Email = "noreply@post.swcs.pro"
};
data.Cc = null; // "cee-maildev@gmx.at,anaheimcore@gmail.com,ceemaildev@yahoo.com";
data.Bcc = null;
data.To = [new ScalewayRequest.EmailAddress()
{
Email = "maildev@alias.swcs.pro"
}];
data.Subject = $"{data.Subject} (test)";
}
try
{
using HttpResponseMessage responseMessage = await Http.PostAsJsonAsync(uri, data, JsonSerializerOptions, token);
ScalewayResponse.Email response = await responseMessage.Content.ReadFromJsonAsync<ScalewayResponse.Email>(JsonSerializerOptions, token);
Logger.LogDebug("Email {id} sent via Scaleway API with status {status}", response.Id, response.Status);
ScalewayResponse.SendEmail response = await responseMessage.Content.ReadFromJsonAsync<ScalewayResponse.SendEmail>(JsonSerializerOptions, token);
if (!responseMessage.IsSuccessStatusCode)
{
throw new Exception($"Could not send message via Scaleway API. Status code: {responseMessage.StatusCode}, Message: {responseMessage.ReasonPhrase}");
}
string id = response.Emails.FirstOrDefault()?.Id;
Logger.LogDebug("Email {id} sent via Scaleway API", id);
}
catch (Exception ex)
{
@@ -9,6 +9,11 @@ public class ScalewayResponse
public Domain[] Domains { get; set; } = [];
}
public class SendEmail
{
public Email[] Emails { get; set; } = [];
}
public class Domain
{
public string Name { get; set; }
+3 -3
View File
@@ -12,10 +12,10 @@ internal class FinchMailModule : FinchModule
{
services.AddHttpClient<ScalewayDispatcher>().RemoveAllLoggers();
services.AddScoped<IMailProvider, MailProvider>();
services.AddScoped<IMailDispatcherResolver, MailDispatcherResolver>();
// use logger mail dispatcher as default implementation
// to use other dispatchers .AddMailDispatcher() should be used
services.AddScoped<IMailDispatcher, LoggerMailDispatcher>();
services.AddScoped<IMailDispatcher, PostmarkDispatcher>();
services.AddScoped<IMailDispatcher, ScalewayDispatcher>();
services.AddOptions<MailOptions>().Bind(configuration.GetSection("Finch:Mails")).Configure(opts =>
{
+3 -4
View File
@@ -7,13 +7,13 @@ using Microsoft.Extensions.Options;
namespace Finch.Mails;
public class MailProvider(IFinchContext finch, IOptionsMonitor<MailOptions> mailOptions, ILogger<IMailProvider> logger, IMailDispatcherResolver dispatcherResolver, IRazorRenderer renderer) : IMailProvider
public class MailProvider(IFinchContext finch, IOptionsMonitor<MailOptions> mailOptions, ILogger<IMailProvider> logger, IMailDispatcher mailDispatcher, IRazorRenderer renderer) : IMailProvider
{
protected ILogger<IMailProvider> Logger { get; set; } = logger;
protected IFinchContext Finch { get; set; } = finch;
protected IMailDispatcherResolver DispatcherResolver { get; set; } = dispatcherResolver;
protected IMailDispatcher Dispatcher { get; set; } = mailDispatcher;
protected IRazorRenderer Renderer { get; set; } = renderer;
@@ -25,8 +25,7 @@ public class MailProvider(IFinchContext finch, IOptionsMonitor<MailOptions> mail
/// <inheritdoc />
public virtual async Task Send(Mail message, CancellationToken token = default)
{
IMailDispatcher dispatcher = await DispatcherResolver.Resolve();
await Send(message, dispatcher, token);
await Send(message, Dispatcher, token);
}
@@ -0,0 +1,16 @@
using Finch.Mails.Dispatchers;
using Microsoft.Extensions.DependencyInjection;
namespace Finch.Mails;
public static class MailsServiceCollectionExtensions
{
/// <summary>
/// Replaces the current mail dispatcher implementation with a new one
/// </summary>
public static IServiceCollection AddMailDispatcher<T>(this IServiceCollection services) where T : class, IMailDispatcher
{
services.Replace<IMailDispatcher, T>(ServiceLifetime.Scoped);
return services;
}
}