Bird
Raised Fist0
Laravelframework~10 mins

Dependency injection in controllers in Laravel - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Dependency injection in controllers
Request comes in
↓
Laravel Router matches route
↓
Controller instantiated
↓
Dependencies injected via constructor or method
↓
Controller method executes with dependencies
↓
Response returned
Laravel receives a request, matches it to a route, creates the controller, injects needed dependencies automatically, then runs the controller method.
Execution Sample
Laravel
class UserController {
  protected $repo;

  public function __construct(UserRepository $repo) {
    $this->repo = $repo;
  }
  public function index() {
    return $this->repo->all();
  }
}
This controller receives a UserRepository automatically injected, then uses it to get all users.
Execution Table
StepActionDependencyController StateOutput
1Request received for /usersNone yetNo controller instanceNone
2Route matched to UserController@indexNone yetNo controller instanceNone
3Instantiate UserControllerUserRepository created and injectedrepo = UserRepository instanceNone
4Call index() methodrepo availablerepo = UserRepository instanceCalls repo->all()
5UserRepository->all() returns user listrepo usedrepo unchangedUser list returned
6Response sent to clientrepo usedrepo unchangedUser list JSON
💡 Controller method finishes and response is sent back to client
Variable Tracker
VariableStartAfter Step 3After Step 4Final
reponullUserRepository instanceUserRepository instanceUserRepository instance
Key Moments - 3 Insights
How does Laravel know what to inject into the controller constructor?
Laravel uses type hints in the constructor to automatically create and inject the correct dependency, as shown in step 3 of the execution_table.
What if the dependency requires its own dependencies?
Laravel resolves nested dependencies automatically by checking the constructor of each dependency, so UserRepository's dependencies are also injected before UserRepository is passed to the controller.
Can dependencies be injected into controller methods instead of constructor?
Yes, Laravel supports method injection where dependencies are passed as parameters to controller methods, resolved automatically before method execution (similar to constructor injection shown in step 4).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the state of the controller after step 3?
Arepo is null
BController is not instantiated
Crepo is a UserRepository instance
Drepo is a string
💡 Hint
Check the 'Controller State' column at step 3 in the execution_table
At which step does Laravel inject the UserRepository dependency?
AStep 1
BStep 3
CStep 2
DStep 5
💡 Hint
Look for when the controller is instantiated and dependencies are created in the execution_table
If the UserRepository had another dependency, how would the execution_table change?
AStep 3 would include creating that dependency first
BStep 4 would inject the new dependency
CStep 1 would create all dependencies
DNo change needed
💡 Hint
Recall Laravel resolves nested dependencies before injecting the main dependency at controller instantiation
Concept Snapshot
Dependency injection in Laravel controllers:
- Laravel auto-injects dependencies by type hinting in constructors or methods.
- Controller is instantiated with dependencies resolved first.
- Dependencies can have their own dependencies, resolved recursively.
- This keeps controllers clean and testable.
- Injection happens before controller method runs.
Full Transcript
When Laravel receives a request, it matches the route to a controller method. Before calling the method, Laravel creates the controller instance. It looks at the constructor's type hints and automatically creates and injects those dependencies. For example, if the controller needs a UserRepository, Laravel creates it and passes it in. Then the controller method runs using that dependency. This process makes code cleaner and easier to test because dependencies are managed automatically. If dependencies have their own dependencies, Laravel resolves those too before injection. This can also happen in controller methods via method injection.

Practice

(1/5)
1. What is the main purpose of dependency injection in Laravel controllers?
easy
A. To automatically provide required objects to the controller
B. To manually create objects inside controller methods
C. To make controllers dependent on global variables
D. To avoid using any external classes in controllers

Solution

  1. Step 1: Understand dependency injection concept

    Dependency injection means Laravel automatically gives the controller the objects it needs without manual creation.
  2. Step 2: Identify the purpose in Laravel controllers

    This keeps controllers clean and easy to test by providing dependencies automatically.
  3. Final Answer:

    To automatically provide required objects to the controller -> Option A
  4. Quick Check:

    Dependency injection = automatic object provision [OK]
Hint: Dependency injection means Laravel gives needed objects automatically [OK]
Common Mistakes:
  • Thinking you must create objects manually inside controllers
  • Confusing dependency injection with global variables
  • Believing dependency injection removes use of external classes
2. Which of the following is the correct way to inject a service into a Laravel controller constructor?
easy
A. public function __construct($service) { $this->service = new Service(); }
B. public function __construct(Service $service) { $this->service = $service; }
C. public function __construct() { $this->service = Service::class; }
D. public function __construct(Service $service) { $service = new Service(); }

Solution

  1. Step 1: Check constructor parameter type hinting

    public function __construct(Service $service) { $this->service = $service; } correctly type hints the Service class in the constructor parameter.
  2. Step 2: Verify assignment to class property

    public function __construct(Service $service) { $this->service = $service; } assigns the injected service to a class property for later use, which is correct.
  3. Final Answer:

    public function __construct(Service $service) { $this->service = $service; } -> Option B
  4. Quick Check:

    Constructor injection = type hint + assign property [OK]
Hint: Type hint service in constructor and assign to property [OK]
Common Mistakes:
  • Not type hinting the service class in constructor
  • Creating new service instance inside constructor instead of injecting
  • Assigning class name string instead of object
3. Given this controller method, what will be the output if the injected service returns 'Hello' from its greet() method?
public function show(Service $service) {
    return $service->greet();
}
medium
A. "Hello"
B. Error: Service not found
C. null
D. "greet"

Solution

  1. Step 1: Understand method injection

    The Service object is injected automatically into the show method by Laravel.
  2. Step 2: Call the greet() method on the injected service

    The greet() method returns the string "Hello", so the method returns "Hello".
  3. Final Answer:

    "Hello" -> Option A
  4. Quick Check:

    Injected service method output = "Hello" [OK]
Hint: Injected method returns service method result directly [OK]
Common Mistakes:
  • Assuming service is not injected and causes error
  • Expecting method name instead of method return value
  • Confusing null with empty string output
4. What is wrong with this controller constructor for dependency injection?
public function __construct(Service $service) {
    $service = new Service();
    $this->service = $service;
}
medium
A. It lacks type hinting for the service parameter
B. It does not assign the service to a class property
C. It creates a new Service instance instead of using the injected one
D. It should not use $this keyword inside constructor

Solution

  1. Step 1: Analyze the constructor parameter and assignment

    The constructor receives a Service object but immediately overwrites it by creating a new instance.
  2. Step 2: Understand why this is wrong

    This defeats dependency injection because the injected object is ignored and a new one is created manually.
  3. Final Answer:

    It creates a new Service instance instead of using the injected one -> Option C
  4. Quick Check:

    Overwriting injected service = wrong [OK]
Hint: Do not create new instance; use injected object directly [OK]
Common Mistakes:
  • Overwriting injected parameter with new instance
  • Forgetting to assign injected object to property
  • Confusing type hinting with variable assignment
5. You want to inject two services, Logger and Mailer, into a Laravel controller and use them in a method. Which constructor and method setup is correct?
hard
A. public function __construct() { $this->logger = new Logger(); $this->mailer = new Mailer(); } public function notify() { $this->logger->log('Notify'); $this->mailer->send(); }
B. public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function notify(Logger $logger) { $logger->log('Notify'); }
C. public function __construct(Logger $logger) { $this->logger = $logger; } public function notify(Mailer $mailer) { $mailer->send(); }
D. public function __construct(Logger $logger, Mailer $mailer) { $this->logger = $logger; $this->mailer = $mailer; } public function notify() { $this->logger->log('Notify'); $this->mailer->send(); }

Solution

  1. Step 1: Check constructor injection of both services

    public function __construct(Logger $logger, Mailer $mailer) { $this->logger = $logger; $this->mailer = $mailer; } public function notify() { $this->logger->log('Notify'); $this->mailer->send(); } correctly injects both Logger and Mailer in the constructor and assigns them to properties.
  2. Step 2: Verify method usage of injected services

    The notify method uses the injected properties to call log and send methods, which is correct.
  3. Final Answer:

    public function __construct(Logger $logger, Mailer $mailer) { $this->logger = $logger; $this->mailer = $mailer; } public function notify() { $this->logger->log('Notify'); $this->mailer->send(); } -> Option D
  4. Quick Check:

    Inject all services in constructor, use properties in methods [OK]
Hint: Inject all services in constructor, use $this->property in methods [OK]
Common Mistakes:
  • Injecting services only in methods instead of constructor
  • Creating new instances inside constructor instead of injecting
  • Mixing constructor and method injection inconsistently
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard