0

In a tiny Symfony 5.4 project, I would like to initialize a class (logger) at application's boot. This class will build a singleton object and will give me the possibility to call the logger like this maClass::logger->error().

I red a bunch of articles speaking about autowiring. I understand the concept, but in some others classes, I can't use the autowiring, that's why I would like to do that.

Here my new class:

<?php

namespace App\Core\Service;

use Psr\Log\LoggerInterface;

class CoreService
{
    private LoggerInterface $logger;

    private static LoggerInterface $loggerSingleton;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;

        $this->initStatic();
    }

    public function initStatic()
    {
        self::$loggerSingleton = $this->logger;
    }

    public static function logger(): LoggerInterface
    {
        return self::$loggerSingleton;
    }
}

Is there a way to do that?

Thanks.

Nico
  • 85
  • 1
  • 9
  • I don't know anything about your code, but the most common case I run into where autowiring is discouraged is an entity, so if that's your case I'd [check this out](https://stackoverflow.com/q/10330704/231316). If not, can you elaborate on why you can't use autowiring? Otherwise, I think your only alternative is to mess around with [global state somehow](https://stackoverflow.com/a/34613882/231316), which I'd strongly discourage. – Chris Haas May 27 '22 at 21:08
  • @ChrisHaas I think a bit about my code where I can't use autowiring, I may have an idea to fix this. I'm not sure if it will work but I will take a look. I can't use the autowiring in some places because of depedencies between services I have. The goal also for my CoreService class is to not have to add it everywhere I will need it. If I can initialize it at one place and call it by using CoreService::logger->error(), it would be much easier – Nico May 30 '22 at 12:38
  • 1
    Can you use a couple of base classes along with a trait that has get/set for your object, and define the [`set`](https://symfony.com/doc/current/service_container/autowiring.html#autowiring-other-methods-e-g-setters-and-public-typed-properties) as `@required`? – Chris Haas May 30 '22 at 12:42
  • @ChrisHaas I think I tried, but never managed to get it work. I may had done something wrong, I will take another look. In the meantime, I managed to remove some depedencies, that allow me now to autowiring my class on controllers, and so I can call my method everywhere along the process. (Not very familiar with Symfony's best practises, that's my first project with) – Nico May 30 '22 at 17:46
  • 1
    That great @Nico! Honestly, you really just need to play around, and if you've programmed without a framework before, it takes a while to "give up control" to a certain degree. If you have some time, I'd strongly recommend watching the [Symfony Casts tutorials](https://symfonycasts.com/), they do a great job of diving into the framework, and sometimes they show you "the hard way" followed by "the easy way" which really helps. – Chris Haas May 30 '22 at 18:18

1 Answers1

0

Thanks for your help @ChrisHaas.

I retried the set approach and it works, I had to change a bit my new class. Instead of autowiring it in all controllers, I created a parent controller that initialize my class (autowiring) as a protected variable, and instead of using maClass::logger()->error(), it's $this->maClass->logger->error().

Nico
  • 85
  • 1
  • 9