Laravel Dependency Injection

You can’t work with a modern framework without tripping over the concept of dependency injection, this paradigm offers a clean, organized, and maintainable way to integrate reusable code as service.

To give an illustration of what I mean, let’s look at the case of creating a newsletter using Mailchimp which may be replaced by other providers down the road.

Install the Mailchimp package:

“spatie/laravel-newsletter” simplifies Mailchimp integration in Laravel. This command installs it using Composer:

1
composer require spatie/laravel-newsletter

Configure the Mailchimp API credentials:

We use config and env instead of hardcoding variables.

1
2
MAILCHIMP_KEY=YOUR_MAILCHIMP_KEY
MAILCHIMP_PREFIX=YOUR_MAILCHIMP_PREFIX

In serveics.php file in the config directory

1
2
3
4
5
6
7
    'mailchimp' => [
        'key' => env('MAILCHIMP_KEY'),
        'prefix' =>env('MAILCHIMP_PREFIX'),
        'lists' => [
            'subscribers' => 'your_list_id'
        ]
    ]

Create the contract

Define an interface in a Services directory, this will force us to have one method so far subscribe.

The first parameter of  the ‘subscribe()’ method is the member’s email address, while the second and final parameter is the list id.

1
2
3
4
5
6
namespace App\Services;

interface NewsLetter
{
    public function subscribe(string $email, string $list = null);
}

Note This interface doesn’t expose any details about how exactly how the subscribe method works.

Contract implementation

A Mailchimp corresponding implementation will be something like the following

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class MailchimpNewsLetter implements NewsLetter
{
   public function __construct(protected ApiClient $client)
   {

   }

    public function subscribe(string $email, string $list = null)
    {
        $list ??= config('services.mailchimp.lists.subscribers');
        return $this->client->lists->addListMember($list,
            ['email_address' => $email, 'status' => 'subscribed']
        );
    }

}

Register the Newsletter service in laravel ServiceProvider

In the public function register(): void of AppServiceProvider.php

1
2
3
4
5
6
7
app()->bind(NewsLetter::class, function () {  
$client = (new ApiClient())->setConfig([  
    'apiKey' => config('services.mailchimp.key'),  
    'server' => config('services.mailchimp.prefix'),  
    ]);  
return new MailchimpNewsLetter($client);  
});

Using the service

Now, in the call site, which is typically a controller, we use the type hint rather than the implementation class.

1
2
3
4
5
public function __invoke(NewsLetter $newsLetter, Request $request) {
	// validation here 
	$newsLetter->subscribe($request->input('email'));
	// doing something here
}
updatedupdated2024-01-172024-01-17