Content · Web Development · PHP

Using Dependency Injection in Larger Projects

Pass service dependencies via constructors and compose them at an application bootstrap.

1 views Published Oct 17, 2026 Updated Oct 17, 2026 admin

Pass service dependencies via constructors and compose them at an application bootstrap boundary. The examples separate the essential operation from the conditions a production implementation must enforce.

What It Does


Pass service dependencies via constructors and compose them at an application bootstrap boundary.

Prerequisites


Use a dedicated development environment with test accounts and records. Separate authorization, validation and error handling from response formatting; never copy demonstration-only secrets into production.

Example 1: Core Behavior


The first example isolates the core operation so its result is easy to understand.

<?php
interface Clock { public function now(): int; }
final class SystemClock implements Clock { public function now(): int { return time(); } }
final class Greeting { public function __construct(private Clock $clock) {} public function message(): string { return 'At ' . $this->clock->now(); } }
echo (new Greeting(new SystemClock()))->message();

Example 2: Alternative or Failure Case


The second example demonstrates an alternative outcome, rule or failure condition.

<?php
interface Notifier { public function send(string $s): void; }
final class MemoryNotifier implements Notifier { public array $sent = []; public function send(string $s): void { $this->sent[] = $s; } }
final class Signup { public function __construct(private Notifier $notifier) {} public function run(): void { $this->notifier->send('Welcome'); } }
$fake = new MemoryNotifier(); (new Signup($fake))->run(); echo count($fake->sent);

Practical Example: Applying the Rule


The practical example shows how to carry the same constraint into application code.

<?php
final class AppConfig { public function __construct(public readonly string $timezone) {} }
final class Formatter { public function __construct(private AppConfig $settings) {} public function zone(): string { return $this->settings->timezone; } }
$settings = new AppConfig('UTC');
echo (new Formatter($settings))->zone();

Important Behavior and Edge Cases


Avoid global service locators and uncontrolled container access inside domain classes.

Comparison with Related Functions or Patterns


ApproachWhen it differs
Using Dependency Injection in Larger ProjectsPass service dependencies via constructors and compose them at an application bootstrap boundary.
Related API or patternFactories handle conditional object construction while constructor injection exposes requirements.

Common Beginner Mistakes


MistakeCorrect approach
Creating dependencies inside a domain method instead of injecting themAvoid global service locators and uncontrolled container access inside domain classes.
Substituting a related API without checking its semanticsFactories handle conditional object construction while constructor injection exposes requirements.

Key Takeaways


  • Pass service dependencies via constructors and compose them at an application bootstrap boundary.
  • Avoid global service locators and uncontrolled container access inside domain classes.
  • Factories handle conditional object construction while constructor injection exposes requirements.

Select this API or pattern based on its documented behavior and the trust boundaries in your own application, and test all external integrations against their actual deployments.

Share this resourceSend this page to someone who may find it useful.