Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Laravel, any downside to using App::make('') rather than constructor injection?

Normally I would just inject dependancies via the constructor, but it gets to be very verbose when the parent class has dependancies and have to pass them through all the children.

The alternative is to use $this->dependancy = App::make('Dependancy') in the parent class alone. Then both the parent and child constructors can be empty. Is there any downside to doing it this way?

like image 565
dwenaus Avatar asked Aug 24 '14 00:08

dwenaus


People also ask

What is Laravel dependency injection?

In Laravel, dependency injection is the process of injecting class dependencies into a class through a constructor or setter method. This allows your code to look clean and run faster. Dependency injection involves the use of a Laravel service container, a container that is used to manage class dependencies.

What is IOC container in Laravel?

The Laravel inversion of control container is a powerful tool for managing class dependencies. Dependency injection is a method of removing hard-coded class dependencies. Instead, the dependencies are injected at run-time, allowing for greater flexibility as dependency implementations may be swapped easily.

What is singleton in Laravel?

The singleton method binds a class or interface into the service container so that Laravel can maintain dependency (when using an interface as the constructor parameter). (Actually Singleton is a design pattern. Singleton implementation always returns the same object on subsequent calls instead of a new instance).

What is service provider and service container in Laravel?

What are service providers in laravel? Service providers in laravel application is the central place where application is bootstrapped. That is, laravel's core services and our application's services, classes and their dependencies are injected in service container through providers.


2 Answers

There is a downside to your approach, doing what you propose will make your application less testable.

What I mean is that if you try to write a unit test for the parent class you will no longer be testing that parent class in isolation. Your test now also depends on the results from the dependency declared inside the parent class.

If you pass this dependency in through constructor injection (or any type of injection) you have control over the dependency and can mock/stub the output from it and better test your parent class in isolation.

like image 76
Christopher Rathgeb Avatar answered Oct 14 '22 10:10

Christopher Rathgeb


First of all there is no downside to use App::make('...') or app('...') but if you use type hinting in the constructor then you don't need to inject the dependencies manually. For example, if you have something like this:

class SomeController extends BaseController {

    protected $otherClass = null;

    public function __construct(SomeOtherClass $otherClass)
    {
        $this->otherClass = $otherClass;
    }
}

Now, if you use SomeController class then Laravel will automatically inject the SomeOtherClass into the SomeController class and if your SomeOtherClass has it's own dependencies then Laravel will inject those as well if they are type hinted. So, you may use Dependency Injection in constructor over App::make(...)/app(...) and it would be better if you use Interface to type hint instead of concrete class. It's been said, program over interface not implementation (concrete class).

Generally speaking, there is one thing in dependency injection technique and it is that, while you compose a class with other objects, then it may look complex. Actually, dependency injection is a way to compose a class by mixing other objects at runtime through constructor method (composition over inheriting) but sometimes it may look complex to find out the object's relationship to each other if there are so many dependencies. Ultimately it's a good design pattern which gives us a way to decouple the objects from each other and you need to chose wisely when to use it.

Update: Actually, in Laravel when you type hint a dependency in the constructor method, the framework automatically injects the dependencies by reading the type of it's dependent object and behind the scene, Laravel uses the App::make(...) method. So, if you don't use dependency injection then you just need to manually use the App::make(...), that's all. In both cases, the App::make() is being used, either automatically by the framework or by the developer. So, use App::make() without any hesitation, it's safe and a better approach to decouple the dependencies from each other.

In other words, if you type hint the dependencies in the constructor method then Laravel will use App::make(...) to automatically inject them but if you don't type hint then You need to manually inject them and in this case you'll use App::make() instead of framework, that's it. For automatic resolving of dependencies, you need to type hint your dependencies but if you manually inject your dependencies then you don't need to type hint them and without type hint, Laravel can't inject any dependencies automatically and it makes sense. Btw, I'm not thinking about testing tho.

like image 25
The Alpha Avatar answered Oct 14 '22 10:10

The Alpha