Providers
Suppose in one of your controllers you want to send an email and for that you create a Mailer library that requires some initial setup before you start sending mails.
class ReportController
{
public function sendReport()
{
// Configure mailer service provider
$mailer = new Mailer('smtp.example.org', 25);
$mailer->setUsername('your username');
$mailer->setPassword('your password');
// Send mail
$mailer->sendMessage([
'to' => 'analyst@example.com',
'from' => 'admin@example.com',
'body' => 'Here is your report',
'subject' => 'Latest financial report',
]);
}
}
What is wrong with the above code? Nothing if it actually works.
But imagine there a number of controller methods where you use this Mailer service class. This will soon become a nightmare to maintain such code because you will keep configuring Mailer instance before sending mails. Right?
What if you could configure your Mailer service once and keep using that instance wherever you wanted in your application?
Although there are a couple of possible solutions to do that, Lightpack supports the concept of provider which are classes to configure your services.
Providers are classes where you register your services in IoC container for easy access.
Creating Provider
From your terminal you can fire this command to create a Mailerprovider.
php console create:provider MailerProvider
This should have generated MailerProvider class in app/Providers directory.
Inside that class you will find a register() method. Note that all providers must implement Lightpack\Support\ProviderInterface:
use Lightpack\Container\Container;
use Lightpack\Support\ProviderInterface;
class MailerProvider implements ProviderInterface
{
public function register(Container $container)
{
$container->register('mailer', function ($container) {
//
});
}
}
In this method you can configure Mailer service as shown:
public function register(Container $container)
{
$container->register('mailer', function ($container) {
$mailer = new Mailer('smtp.example.org', 25);
$mailer->setUsername('your username');
$mailer->setPassword('your password');
return $mailer;
});
}
Registering Provider
You need to register the provider class in order to access the service.
Open boot/providers.php file and just add your provider class at the end of the providers array.
<?php
return [
App\Providers\MailerProvider::class,
];
Framework providers are loaded first, then your application providers. If your provider depends on services from another provider, make sure to order them correctly.
Using Provider
Now you can access this service using the alias mailer by calling app('mailer') function in your controller.
class ReportController
{
public function sendReport()
{
app('mailer')->sendMessage([
'to' => 'analyst@example.com',
'from' => 'admin@example.com',
'body' => 'Here is your report',
'subject' => 'Latest financial report',
]);
}
}
Aliasing Services
You can create aliases for your services to enable type-hinted dependency injection:
public function register(Container $container)
{
$container->register('mailer', function ($container) {
return new Mailer('smtp.example.org', 25);
});
// Create alias for class name
$container->alias(Mailer::class, 'mailer');
}
Now you can access the service using either the alias or the class name:
app('mailer'); // Via alias
app(Mailer::class); // Via class name
As you can see that in providers you bind services in container, so you should read more about containers in Lightpack.