DEV Community

Cover image for DI and Service Locator
Kenta Takeuchi
Kenta Takeuchi

Posted on • Originally published at bmf-tech.com

DI and Service Locator

This article was originally published on bmf-tech.com.

Overview

Summarizing the differences between DI and Service Locator

What is DI

  • A type of design pattern
  • Dependency Injection
    • Separates dependencies between objects
    • Ensures necessary objects are injected at runtime
  • Makes testing easier

Implementing the DI Pattern

Let's implement the DI pattern (Constructor Injection). Note that the DI pattern includes methods other than constructor injection, such as setter injection and method injection. For comparison, both non-DI and DI patterns will be implemented.

Non-DI Pattern

<?php
class SlackNotification
{
    public function notify(string $message)
    {
        echo $message;

        return $this;
    }
}

class Application
{
    protected $message;

    public function __construct()
    {
        $this->notification = new SlackNotification();
    }

    public function alert(string $message)
    {
        $this->notification->notify($message);
    }
}

// client
$application = new Application();
$application->alert('slack alert');
Enter fullscreen mode Exit fullscreen mode

DI Pattern

<?php

interface NotificationInterface
{
    public function notify(string $message);
}

class SlackNotification implements NotificationInterface
{
    public function notify(string $message)
    {
        echo $message;

        return $this;
    }
}

class Application
{
    protected $message;

    public function __construct(NotificationInterface $notification) // DI
    {
        $this->notification = $notification;
    }

    public function alert(string $message)
    {
        $this->notification->notify($message);
    }
}

// client
$slackNotification = new SlackNotification();
$application = new Application($slackNotification); // DI
$application->alert('slack alert!');
Enter fullscreen mode Exit fullscreen mode

Application does not hold the responsibility of SlackNotification, and only depends on NotificationInterface. Application is structured to accept (depend on) SlackNotification in the constructor.

The dependency injection part can be mocked, making it easier to test.

// For test
$mockNotification = new MockNotification(); // MockNotification implementing NotificationInterface
$application = new Application($mockNotification);
$application->alert('mock alert!');
Enter fullscreen mode Exit fullscreen mode

Advantages and Disadvantages of DI

Advantages

  • Reduces coupling between objects and clarifies dependencies
  • Resistant to changes
  • Easier to test

Disadvantages

  • Increases the number of files
  • Potential decrease in program execution speed

DI Container

  • A framework that provides DI functionality
  • Offers a container to manage dependencies collectively

What is a Service Locator

  • A design pattern that abstracts the retrieval of services (objects)
  • Considered an anti-pattern
    • Adds one more dependent class (the container class of the service locator)
    • Makes the container class difficult to test
    • Makes it hard to understand dependent classes
    • For more details, see "PHP The Right Way"

Something like this

<?php

class Application
{
    public function __construct($container)
    {
        $this->slackNotification = $container['slack.notification'];
    }
}

$application = new Applicaion($container);
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)