2

Maybe it's a silly question, but the official documentation is not clear for me at that place. It says that dependency injection is automatically resolved e.g. in Controllers. But in my routing, I bind my route to a class which doesn't inheritance from Controller class. And automatic injection works! Does it mean that resolving every route automatically uses ServiceContainer and resolves dependencies?

In docs we have:

Alternatively, and importantly, you may "type-hint" the dependency in the constructor of a class that is resolved by the container, including controllers, event listeners, middleware, and more. Additionally, you may type-hint dependencies in the handle method of queued jobs. In practice, this is how most of your objects should be resolved by the container.

And it says "controllers, event listeners, middleware, AND MORE". Could you show me other places, where autoinjection works?

I'm using Laravel >5.8. Thank you.

1
  • 1
    app()->make(MyClass::class) will also use dependency injection to resolve dependencies Commented Jan 28, 2020 at 11:57

2 Answers 2

1

Dependency injection depends on how you call a function/method, not the function itself.

[...] you may "type-hint" the dependency in the constructor of a class that is resolved by the container

"Resolved by the container" means that you (or in this case the Laravel router) are calling it through the container.

To automatically resolve the dependencies in the constructor you can use app()->make():

$myThing = app()->make(MyClass::class);

This will give you an instance of MyClass with the constructor dependencies resolved.

To use DI on a method you can use app()->call():

$result = app()->call([$myThing, 'someMethod']);

In general, Laravel uses DI almost everywhere. I always assume it works, and if it doesn't you can simply resolve the dependency manually.

Note: The is based on Laravel 5.4.26 but most, if not all, information should still be correct.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer. I know what to do to manually resolve dependencies with service container. But I would like to know when Laravel uses it by default. Like when we use routing, our Controller class is resolved by the container. But when I create an instance with the "new" keyword, it isn't. I thought it's associated with inheriting after Controller class. But it will resolve it by container even if it's regular PHP class. So I try to expand my knowledge about how exactly Laravel and it's flow works.
DI does not depend on the class whose dependencies you are resolving, only on how it is called. It even works with simple non-class functions. Laravel automatically adds DI to pretty much any class you instantiate or method you call through Laravel instead of manually, e.g. routes (including inline functions). The docs use "and more" because listing all cases would be quite long. If you search the Laravel source for resolve you'll find a lot of them including routes, jobs, seeders, migrations, validations and many more.
0
I found this answer useful, so thank you!  I am  learning more and more about DI.  However, I am also somewhat wondering why 'new' cannot be more fully resolved.  See below:
// SupportLevel1 is an interface
    class LevelBClass {
        private $slb = NULL;
        public function __construct(SupportLevel1 $slb){
            $this->slb = $slb;
        }

    };
    //// THE FOLLOWING DOES NOT WORK.  NEED TO SUPPLY
    //// ARG TO CONSTRUCTOR.
    //// $objLevelBClass = new LevelBClass();

    // This method works, but requires *some* manual intervention.
    $objLevelBClass = new LevelBClass(app(SupportLevel1::class));

    /*
     * Here the technique is to use the helper app and its
     * resulting make method.  However, we give it
     * the top level class - that is LevelBClass - which
     * we know will need to resolve the interface
     * argument to its constructor.  From a top down, stand
     * back approach, it works like a charm!
     */
    $objLevelBClass = app()->make(LevelBClass::class);

1 Comment

If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.