Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kjnvalkjnsb's avatar

IoC Container - Automatic Resolution or Closure Callbacks

Hello,

I'm looking for some advice on how I should be handling my dependency injections.

I see that in 4.3 there is much more focus on Service Providers and binding our services into the container but I'm currently used to using Automatic Resoltuion and passing my services in through constructors.

If I chose to go down the route of using Service Providers and binding my services which I want to, what is the best way for me to inject my dependencies? Do I still need to inject them into my constructors or in my construct methods just use App::make();?

I hope I haven't got myself confused on all of this and hope you can help : ).

0 likes
5 replies
ATOM-Group's avatar

Nothing here has changed from 4.2 to 4.3. You can still do automatic resolution / constructor injection as long as you're using concrete classes, but the "proper" way to do it is use interfaces/abstractions instead of concrete implementations. Any interface/abstract type hint in a constructor needs to be told which concrete implementation to use, hence you need to register that implementation in the IoC via a service provider.

Consider this example:

 class ProfileController
 {
       public function __construct(UserRepositoryInterface $repo)
       {
             ....
       }
 }

The interface is an abstraction, so the IoC does not know how to resolve it. Thus you will need to register which UserRepositoryInterface you are implementing (e.g. EloquentUserRepository or DoctrineUserRepository etc...).

If you do this:

 class ProfileController
 {
       public function __construct(User $user)
       {
             ....
       }
 }

Then as long as User is a concrete model/class, the IoC will be able to resolve it for you, just like it currently does.

Hope that helps.

kjnvalkjnsb's avatar

Thank tag, that really helps.

If I'm using concrete classes and use App::bind(); to bind my objects into the IoC, in that instance should I be using App::make();?

My main concern is if there is a performance difference between the two and which would be best.

kjnvalkjnsb's avatar

I should probably be a little clearer on my last post.

If I'm not using interfaces and am using the Service Provider to bind my services. Do I still inject my classes through the constructor or only use App::make(); to get them?

ATOM-Group's avatar
Level 11

You'll need to do both. Dependency injection always involves two steps:

First, define the dependencies the class will use in its constructor

class MyClass
{
     // Can do this with or without type hints
     public function __construct($dependency1, $dependency2) 
     {
           ...
     }
}

Then from outside of that class, instantiate those dependencies and push them into that class:

$dependency1 = new Dependency1;
$dependency2 = new Dependency2;
$myClass = new MyClass($dependency1, $dependency2);

So how do you do the second step using Laravel & App::bind(), App::make()? Like this (you actually have two ways)

// Here's one way: it's basically the same as the above - 
// we use the 'new' keyword to instantiate the two dependencies of 'MyClass'

App::bind('MyClass', function() {
     $dependency1 = new Dependency1;
     $dependency2 = new Dependency2;
     return new MyClass($dependency1, $dependency2)
});

// Here's another way: we use App::make() to create the two dependencies:

App::bind('MyClass', function() {
     $dependency1 = App::make('Dependency1');
     $dependency2 = App::make('Dependency2');
     return new MyClass($dependency1, $dependency2)
});

So why use App::make() for creating the dependencies instead of the new keyword?

Because if Dependency1 & 2 had dependencies of their own, you wouldn't want to have to manually wire together that object graph every time. App::make() loads all of those sub-dependencies for you.

Consider this final example:

App::bind('MyClass', function() {

     // Create Dependency1 the hard/manual way, every time you want to use it....

     $dependency1 = new Dependency1(
         new OtherDependency(
             new AnotherDependency('some', 'config', 'data', 'here'),
             new MoreDependencies,
         ),
         new ThisIsTiringDepenency,
         new MotherOfGodDoINeedToDoThisEveryTime('nope', 'just', 'use', 'App::make()')?
      );

     // Or use App::make() to do it for you to save yourself a lot of time

     $dependency1 = App::make('Dependency1');

     return new MyClass($dependency1)
});

Just as a side not that's worth mentioning, don't use App::make() from inside your classes, that's using it like a service locator which is an anti-pattern, and hides the true dependencies of the class. Always inject your dependencies through a constructor, and then bind them into the IoC from a service provider using a combination of App::bind() and App::make() and new as needed

1 like
kjnvalkjnsb's avatar

That was perfect thank you. Understanding that there are a few ways to inject dependancies in Laravel I wanted to know the best way but with an explanation. Thanks again!

Please or to participate in this conversation.