Contao-Camp 2024
Ergebnis 1 bis 3 von 3

Thema: [gelöst] Dependency Injection bei DCA Operationen

  1. #1
    Contao-Nutzer Avatar von chatjack
    Registriert seit
    02.09.2012.
    Ort
    Essen
    Beiträge
    160

    Standard [gelöst] Dependency Injection bei DCA Operationen

    Hallo zusammen,

    ich setze mich gerade etwas mit Dependency Injections auseinander, was inzwischen auch ganz gut klappt.

    Wenn ich das jetzt richtig verstanden habe werden automatisch alle benötigten Argumente an die Klasse mitgegeben, die im Constructor stecken, wenn in der übergeordneten Klasse, die auf diese zugreift, per Annotation der ServiceTag "controller.service_arguments" mitgegeben wird.

    Die übergeordnete Klasse sieht wie folgt aus.

    PHP-Code:
    namespace App\Service;

    use 
    Terminal42\ServiceAnnotationBundle\Annotation\ServiceTag;
    use 
    App\Stats;
    use 
    Contao\DataContainer;

    /**
     * @ServiceTag("controller.service_arguments")
     */
    class ServiceStats {
        
        private 
    $stats;

        public function 
    __construct(Stats $stats)
        {
            
    $this->stats $stats;
        }
        
        public function 
    showStats(DataContainer $dc)
        {
            return 
    $this->stats->showStats($dc);
        }
        

    Diese besitzt per Annotations den ServiceTag "controller.service_arguments" und bindet über den Constructor die Klasse Stats ein.

    Das klappt soweit auch wunderbar. Die beiden Argumente im Constructor der Klasse Stats werden automatisch angehangen.

    PHP-Code:
    namespace App;

    use 
    Doctrine\DBAL\Connection;
    use 
    Symfony\Component\Filesystem\Filesystem;
    use 
    Contao\DataContainer;
    use 
    Terminal42\ServiceAnnotationBundle\Annotation\ServiceTag;

    class 
    Stats {
        
        public function 
    __construct(Connection $dbFilesystem $filesystem)
        {
            ...
            }

        ...

        public function 
    showStats(DataContainer $dc) {
            return 
    "Hooray! It works!";
        }


    Das wird aktuell als Operator innerhalb einer DCA-Liste genutzt, der zurzeit nur den Testtext "Hooray! It works!" ausgibt.

    PHP-Code:
    array_insert($GLOBALS['BE_MOD'], 1, [
            
    'stats' => [
                
    'report' => [
                    
    'tables' => ['tl_stats_report'],
                    
    'showStats' => [App\Service\ServiceStats::class, 'showStats']
                ]
            ]
        ]
    ); 
    Zurzeit nutze ich die Klasse ServiceStats mehr oder weniger als Krücke, da diese sich per Annotations um die Dependency Injections kümmert. Am liebsten würde ich direkt auf die Klasse Service verweisen. Mir ist jedoch nicht ganz klar, wie in diesem Fall die Dependency Injections funktionieren.

    Muss ich hier eine service.yml anlegen über die ich die Argumente an die Klasse übergebe und diese auf Public setzen, oder gibt es auch hier einen eleganteren Weg.

    Besten Dank und
    lieben Gruß
    Dennis
    Geändert von chatjack (25.08.2021 um 15:28 Uhr)

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    33.896
    Partner-ID
    10107

    Standard

    Für eigene Backend Module gibt es noch keinen modernen Ersatz - außer Backend Routes: https://docs.contao.org/dev/guides/back-end-routes/

    In klassischen Backend Modulen müsstest du dir Services über System::getContainer()->get() holen (diese müssen dann aber public sein).
    Geändert von Spooky (24.08.2021 um 08:51 Uhr)
    » sponsor me via GitHub or PayPal or Revolut

  3. #3
    Contao-Nutzer Avatar von chatjack
    Registriert seit
    02.09.2012.
    Ort
    Essen
    Beiträge
    160

    Standard

    Besten Dank! Leider wurden meine Controller-Klassen nicht mehr gefunden, nachdem ich die Stats-Klasse in der services.yaml hinzugefügt hatte, weshalb ich das Ganze etwas anpassen musste. Filesystem wurde aus App\Stats entfernt, sodass jetzt nurnoch die Datenbank-Verbindung benötigt wird. In diesem Zuge habe ich den Tag "controller.service_arguments" als Annotation entfernt und mit in die services.yml gepackt.

    So habe ich es jetzt lösen können.

    config/services.yml
    Code:
    services:
        app.stats:
            class: App\Stats
            arguments:
                - '@database_connection'
            public: true
    
        App\Controller\UpdateVisitsController:
            arguments:
                - '@app.stats'
            tags:
                - controller.service_arguments
    
        App\Controller\UpdateDatabaseController:
            arguments:
                - '@app.stats'
            tags:
                - controller.service_arguments
    app/Resources/config.php
    PHP-Code:
    array_insert($GLOBALS['BE_MOD'], 1, [
            
    'stats' => [
                
    'report' => [
                    
    'tables' => ['tl_stats_report'],
                    
    'showStats' => ['app.stats''showStats']
                ]
            ]
        ]
    ); 
    src/Stats.php
    PHP-Code:
    namespace App;

    use 
    Doctrine\DBAL\Connection;
    use 
    Contao\DataContainer;

    class 
    Stats {

        private 
    $db;
        
        public function 
    __construct(Connection $db)
        {
            
    $this->db $db;
        }

        public function 
    showStats(DataContainer $dc) {
            return 
    "Hooray! It works!";
        }

        ...


    src/Controller/UpdateVisitsController.php
    PHP-Code:
    namespace App\Controller;

    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    App\Stats;

    /**
     * @Route("/update_visits", name=UpdateVisitsController::class)
     */
    class UpdateVisitsController
    {
        private 
    $stats;

        public function 
    __construct(Stats $stats)
        {
            
    $this->stats $stats;
        }

        public function 
    __invoke(Request $request): Response
        
    {
            ...
        }

    src/Controller/UpdateDatabaseController.php
    PHP-Code:
    namespace App\Controller;

    use 
    Symfony\Component\HttpFoundation\Request;
    use 
    Symfony\Component\HttpFoundation\Response;
    use 
    Symfony\Component\Routing\Annotation\Route;
    use 
    App\Stats;

    /**
     * @Route("/update_database", name=UpdateDatabaseController::class)
     */
    class UpdateDatabaseController
    {
        private 
    $stats;

        public function 
    __construct(Stats $stats)
        {
            
    $this->stats $stats;
        }

        public function 
    __invoke(Request $request): Response
        
    {
            ...
        }

    Geändert von chatjack (24.08.2021 um 14:17 Uhr)

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •