Zend Framework

Zend Framework 3 Tutorial – Chapter 9: Services and Dependency Injection

Chapter 9: Services and Dependency Injection in Zend Framework 3

✅ Introduction

In Zend Framework 3, Services are reusable classes that provide functionality such as business logic, database access, or third-party integrations. The ServiceManager is a powerful Dependency Injection (DI) container that manages object creation and dependencies automatically.

✅ Key Concepts

  • Service: A class that performs specific tasks (e.g., UserService for user operations).
  • Dependency Injection: A design pattern where dependencies are passed into a class instead of being created inside it.
  • ServiceManager: Zend Framework’s built-in container for managing services and their dependencies.

✅ Creating a Service Class


// module/Application/src/Service/UserService.php
namespace Application\Service;

class UserService {
    public function getUserById($id) {
        // Example: Fetch from database (mock for now)
        return [
            'id' => $id,
            'name' => 'John Doe',
            'role' => 'user'
        ];
    }
}

✅ Registering the Service

Register your service in the module.config.php file:


return [
    'service_manager' => [
        'factories' => [
            Application\Service\UserService::class => InvokableFactory::class,
        ],
    ],
];

✅ Using the Service in a Controller


// module/Application/src/Controller/UserController.php
namespace Application\Controller;

use Application\Service\UserService;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class UserController extends AbstractActionController {
    private $userService;

    public function __construct(UserService $userService) {
        $this->userService = $userService;
    }

    public function profileAction() {
        $id = $this->params()->fromRoute('id', 1);
        $user = $this->userService->getUserById($id);

        return new ViewModel(['user' => $user]);
    }
}

✅ Injecting Service into Controller with Factory


// module/Application/src/Factory/UserControllerFactory.php
namespace Application\Factory;

use Application\Controller\UserController;
use Application\Service\UserService;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;

class UserControllerFactory implements FactoryInterface {
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
        $userService = $container->get(UserService::class);
        return new UserController($userService);
    }
}

✅ Update module.config.php


return [
    'controllers' => [
        'factories' => [
            Application\Controller\UserController::class => Application\Factory\UserControllerFactory::class,
        ],
    ],
];

✅ Dependency Injection Benefits

  • Removes tight coupling between classes.
  • Makes unit testing easier (mock dependencies).
  • Improves code reusability and maintainability.

✅ Best Practices

  • Always inject dependencies via the constructor.
  • Keep services focused on one responsibility (Single Responsibility Principle).
  • Use factories for complex services that require multiple dependencies.
  • Leverage the ServiceManager instead of creating objects manually.

✅ Exercise

  • Create a PostService class to fetch blog posts.
  • Register the service in module.config.php.
  • Inject the service into a PostController using a factory.
  • Display a list of posts in a view template using the injected service.

Leave a Reply

Your email address will not be published. Required fields are marked *