-
Notifications
You must be signed in to change notification settings - Fork 1
EmailService
the email service is what gives you the abstraction over the email-sending logic, it only needs the message to be sent and returns a result, the actual sending logic is implemented at the Channel level.
the email service is given to you as an interface IEmailService with multiple functions to send the emails, and there are two options to get the email service instance:
- using EmailServiceFactory: create an instance of the email service from a factory.
- using DI: get the email service instance through dependency injection.
before talking about how we can get an instance of the email service we should talk about the dependencies the Email Service needs in order for it to work. if you looked the email service constructor you will see it requires you to supply two inputs:
- the list of channels used for sending the emails.
- an instance of
EmailServiceOptions.
the options are what tweaks the email service behaviors, for now, there are not many options, what we have now is:
- PauseSending: to pause the sending of emails, if set to true nothing will be sent.
- DefaultFrom: You can set the default Sender email so that you don't have to do it each time on the message, note that if you have specified a Sender email on the message this value will be ignored.
- DefaultEmailDeliveryProvider: Specify the default channel that should be used to send the emails, because you can configure multiple channels you should indicate which one you want to use.
so let's see how we can get the email service instance.
var emailService = EmailServiceFactory.Instance
.UseOptions(options =>
{
/*
* if set to true we will not send any emails,
* great if we don't want to send emails while testing other functionalities
*/
options.PauseSending = false;
/* used to specify the default form to be used when sending the emails */
options.DefaultFrom = new MailAddress("from@email.net");
/* set the default channel to be used for sending the emails */
options.DefaultEmailDeliveryProvider = SmtpEmailDeliveryProvider.Name;
})
// register the channels
.UseSmtp(options => options.UseGmailSmtp("your-email@gmail.com", "password"))
.Create();on the EmailServiceFactory class you will find a static property Instance that gives you an instance of the factory then you will have access to three methods on the factory:
- UseOptions(): to configure the email service options.
- UseChannel(): to register the channels to be used for sending emails.
- Create(): to create an instance of the EmailService.
starting with UseOptions() this method is what is used to supply the email service options, and the only required option to be set is DefaultEmailDeliveryProvider because you can supply multiple channels to the EmailService you must tell which one is the default one to be used for sending the emails.
UseChannel() takes an instance of the channel, like so: UseChannel(new SmtpEmailDeliveryProvider(configuration)), but you're not going to use this method, instead you will use the extension methods given to you by the channels as we seen on the example above, the SMTP channel has an extension method UseSmtp() that will allow you to register it, for more info on the channels checks out the wiki page.
finally Create() will simply create an instance of the EmailService.
you only need to create the email service once and reuse it in your app.
now we have an instance of the EmailService let's see what we can do with it.
to register Email.Net with DI all you have to do is call the AddEmailNet method on the Services collection like so:
// add Email.Net configuration
services.AddEmailNet(options =>
{
options.PauseSending = false;
options.DefaultFrom = new MailAddress("from@email.net");
options.DefaultEmailDeliveryProvider = SmtpEmailDeliveryProvider.Name;
})
.UseSmtp(options => options.UseGmailSmtp("your-email@gmail.com", "password"));then you can inject the Email Service in your classes, and constructors, using IEmailService
the emails service exposes two functions Send() and SendAsync() with multiple overloads, and both return EmailSendingResult.
the most basic function to send the email message, you supply the message, and the default channel set in the email service options will be used to send the email.
//Get the email service
var emailService = EmailServiceFactory.Instance
.UseOptions(options =>
{
options.PauseSending = false;
options.DefaultFrom = new MailAddress("from@email.net");
options.DefaultEmailDeliveryProvider = SmtpEmailDeliveryProvider.Name;
})
.UseSmtp(options => options.UseGmailSmtp("your-email@gmail.com", "password"))
.Create();
// create the message
var message = EmailMessage.Compose()
.To("to@email.net")
.WithSubject("test email")
.WithPlainTextContent("this is a test email")
.WithHtmlContent("<p>this is a test email</p>")
.Build();
// send the message
var result = emailService.Send(message);
// or
var result = await emailService.SendAsync(message);using the given channel_name we will look at the list of channels and we will get the channel that match the given name if nothing is found an exception of type EmailDeliveryProviderNotFoundException will be thrown if we find the channel we will use it to send the email
//Get the email service
var emailService = EmailServiceFactory.Instance
.UseOptions(options =>
{
options.PauseSending = false;
options.DefaultFrom = new MailAddress("from@email.net");
options.DefaultEmailDeliveryProvider = SmtpEmailDeliveryProvider.Name;
})
.UseSmtp(options => options.UseGmailSmtp("your-email@gmail.com", "password"))
.UseSocketlabs(apiKey: "KEY_SLMSDO4541WC", serverId: 415123)
.Create();
// create the message
var message = Message.Compose()
.To("to@email.net")
.WithSubject("test email")
.WithPlainTextContent("this is a test email")
.WithHtmlContent("<p>this is a test email</p>")
.Build();
// send the message using SocketLabs
var result = emailService.Send(message, SocketLabsEmailDeliveryProvider.Name);
// or
var result = await emailService.SendAsync(message, SocketLabsEmailDeliveryProvider.Name);
Send(Message message, IEmailDeliveryProvider channel) & SendAsync(Message message, IEmailDeliveryProvider channel)
this overload allows you to specify the channel instance that will be used for sending the email message so that if you have an instance of channel you can supply it directly.
//Get the email service
var emailService = EmailServiceFactory.Instance
.UseOptions(options =>
{
options.PauseSending = false;
options.DefaultFrom = new MailAddress("from@email.net");
options.DefaultEmailDeliveryProvider = SmtpEmailDeliveryProvider.Name;
})
.UseSmtp(options => options.UseGmailSmtp("your-email@gmail.com", "password"))
.Create();
// create the message
var message = EmailMessage.Compose()
.To("to@email.net")
.WithSubject("test email")
.WithPlainTextContent("this is a test email")
.WithHtmlContent("<p>this is a test email</p>")
.Build();
// get the channel that will be used for sending the email, this can be any logic that will instantiate an instance of the channel.
var channel = GetChannelInstance();
//Send the message using the given channel instance
var result = emailService.Send(message, channel);
// or
var result = await emailService.SendAsync(message, channel);if the message doesn't have a From (sender) we will use the value supplied in the EmailService options, we should note that if the "from" (sender) is not specified either on the EmailserviceOptions or Message, an exception of type ArgumentException because the sender email is required.
this class is what will report the sending result, there is an IsSuccess property that you can use to check if the sending has succeeded or not, if the sending failed you can check the Errors property to get more info on the cause of the failure.