Because of Masonite's Service Container, It is extremely easy to make drivers that can be used by simply adding your service provider.
Masonite comes shipped with a Service Provider called MailProvider
which loads a few classes into the container as well as boots the default mail driver using the MailManager
. This manager class will fetch drivers from the container and instantiate them. We can look at the MailProvider
class which will gives us a better explanation as to what's going on:
We can see here that because we are only binding things into the container and we don't need the WSGI server to be running, we set wsgi = False
. Service Providers that set wsgi
to False
will only run when the server starts and not on every request.
We can see here that we are binding a few drivers into the container and then binding the MailManager
on boot. Remember that our boot method has access to everything that has been registered into the container. The register methods are executed on all providers before the boot methods are executed.
The MailManager
here is important to understand. When the MailManager
is instantiated, it accepts the container as a parameter. When the MailManager
is instantiated, it fires a create_driver
method which will grab the driver from the configuration file and retrieve a MailXDriver
from the container. The create_driver
method is a very simple method:
Notice that when the driver is created, it tries to get a Mail{0}Driver
from the container. Therefore, all we need to do is register a MailXDriver
into the container ('X' being the name of the driver) and Masonite will know to grab that driver.
So now we know that we need a MailXDriver
so let's walk through how we could create a maildrill
email driver.
We can simply create a class which can become our driver. We do not need to inherit anything, although Masonite comes with a BaseMailDriver
to get you started faster and all drivers should inherit from it for consistency reasons. You can make your driver from a normal class object but it will be harder and won't be considered in Pull Requests.
Let's create a class anywhere we like and inherit from BaseMailDriver
:
Great! We are almost done. We just have to implement one method on this class and that's the send
method. All other methods like to
and template
are inherited from the BaseMailDriver
class. You can find out how to send an email using Maildrill and implement it in this send
method.
We can look at other drivers for inspiration but let's look at the MailMailgunDriver
class now:
If you are wondering where the self.message_body
and self.config
are coming from, check the BaseMailDriver
. All driver constructors are resolved by the service container so you can grab anything you need from the container to make your driver work. Notice here that we don't need a constructor because we inherited it from the BaseMailDriver
Since the MailManager
class creates the driver on boot, we can simply register the driver into the container via any service providers register method. We could create a new Service Provider and register it there. You can read more about created Service Providers under the Service Providers documentation. For now, we will just register it from within our AppProvider
.
Our AppProvider
class might look something like this:
Great! Our new driver is registered into the container. It is now able to be created with Masonite's MailManager
class. We can retrieve your new driver by doing:
If we want the MailManager
to use our new driver by default, change the DRIVER
in our config/mail.py
file. In addition, you may have the users of your driver require a special dictionary entry to the DRIVERS
dictionary:
This way, users can easily swap drivers by simply changing the driver in the config file.
That's it! We just extended our Masonite project and created a new driver. Consider making it available on PyPi so others can install it!