laravelsingletonlaravel-8soa

Is app(FQCN); enough to create a service in Laravel?


I'm new to Laravel, having mostly worked with Symfony.

Recently, I saw a piece of code that looked something like this:

<?php 

namespace MyApp\SomeNamespace;

use MyApp\UserInteraction\Filter;

class MyClass {

    public function myMethod(){

        $filter = app(Filter::class);

        ...

I assume this does something like create or retrieve a singleton. Assuming this is standard practice in Laravel, and not something specific to the app I was looking at, are there any additional steps needed to register a service?

(In Symfony, we would usually have an attribute, a few lines of XML or some YAML that would define service attributes. I tried looking into the helpers.php file to see what was going on, and while this gave me some idea of what the app() function might be doing, it didn't tell me whether there are additional steps needed to register a class as a service in Laravel.)

While I looked at several other questions and tutorials to see what they said, they all referred to an app.config file that isn't present in this application. So I assume the situation has changed in later versions of Laravel.


Solution

  • If I'm not wrong the Laravel will automatically resolve your Service that you want to inject:

    class ExampleController
    {
        // The ExampleService will be automatically resolve
        public function __construct(ExampleService $service) {}
    }
    

    The app() helper returns an instance of Laravel Container but if you add an FQCN inside it as a parameter it will resolve that class:

    app(); // it will return a instance of container
    
    app()->make(Filter::class); // it will resolve the Filter::class
    
    app(Filter::class); // ^ the same as the above
    

    If you want to bind a service class to an interface let says:

    interface House {}
    
    class AncientHouse implements House {}
    
    class HouseBuiler
    {
        public function __construct(House $house) {}
    }
    

    If you want to use the House interface instead of the exact AncientHouse class you need to bind it to the ServiceProvider so that the Container can guess that what you want to inject is the AncientHouse class.

    In the register() method inside the AppServiceProvider

    public function register()
    {
        $this->app->bind(House::class, AncientHouse::class);
    }
    

    My english is bad so I hope I explain it properly.

    References:

    Service Container

    Service Providers