lukencode / FluentEmail

All in one email sender for .NET. Supports popular senders (SendGrid, MailGun, etc) and Razor templates.
https://lukelowrey.com/dotnet-email-guide-2021/
MIT License
2.93k stars 429 forks source link

Reading SMTP settings from Config #147

Open McPhale opened 5 years ago

McPhale commented 5 years ago

Before moving to .net core, we used ActionMailer for our razor-templated emails. I was able to dynamically configure whether our emails went to disk, or to our smtp server using the mailSettings section of web.config + config transforms.

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\temp\" />
        <network host="localhost" />
      </smtp>
   </mailSettings>
  </system.net>

Is there a similar way to do this using appsettings.json in conjunction with .AddSMTPSender() in Startup.cs? I'm open to other suggestions as well if that's not best practice.

McPhale commented 5 years ago

So I ended up coming up with something like this that seems to work; not sure if there's a better way to do it or not.

Startup.cs

            var configSender = new SmtpClient()
            {
                Host                    = Configuration.GetSection("smtp").GetValue<string>("host"),
                DeliveryMethod          = Configuration.GetSection("smtp").GetValue<SmtpDeliveryMethod>("deliveryMethod"),
                PickupDirectoryLocation = Configuration.GetSection("smtp").GetValue<string>("specifiedPickupDirectory:pickupDirectoryLocation"),
            };

            services.AddFluentEmail("test@test.test").AddSmtpSender(configSender);

Appsettings.json

  "smtp": {
    "deliveryMethod": "Network",
    "host": "herp.derp.com"
  }

Appsettings.Development.json

    "smtp": {
      "deliveryMethod": "SpecifiedPickupDirectory",
      "specifiedPickupDirectory": {
        "pickupDirectoryLocation": "C:\\temp"
      },
      "host":  "localhost"
  }
Sebbs128 commented 2 years ago

For what it's worth, I came up with the below for something more config-driven. In this case, you would just add PickupDirectoryLocation (and any other properties you want configured) to SmtpClientSettings and initialise the SmtpClient.PickupDirectoryLocation property (and others) from that.

public static IServiceCollection AddFluentSmtpEmail(this IServiceCollection services)
{
    return services
        .AddTransient(serviceProvider =>
        {
            var options = serviceProvider.GetService<IOptions<SmtpClientSettings>>();

            return new SmtpClient(options.Value.HostName, options.Value.Port)
            {
                Credentials = options.Value.Credentials,
                EnableSsl = options.Value.SSL,
            };
        })
        .AddTransient<ISender>(serviceProvider =>
        {
            var smtpClient = serviceProvider.GetService<SmtpClient>();
            return new SmtpSender(smtpClient);
        })
        .AddSingleton<ITemplateRenderer>(_ => new RazorRenderer())
        .AddTransient<IFluentEmail>(serviceProvider =>
        {
            var options = serviceProvider.GetService<IOptions<FluentEmailSettings>>();
            return new Email(
                serviceProvider.GetService<ITemplateRenderer>(),
                serviceProvider.GetService<ISender>(),
                options.Value.DefaultFromEmail,
                options.Value.DefaultFromName ?? options.Value.DefaultFromEmail);
        })
        .AddTransient<IFluentEmailFactory, FluentEmailFactory>();
}