Home > Blockchain >  DependencyInjection in AbstractEntity
DependencyInjection in AbstractEntity

Time:05-18

i started working on a new Symfony 6.0 project.

I created a new Entity called Project. In this entity I want to set the created_by property automaticlly on PrePersist (hook) call... Therefore I created an AbstractEntity to extend the original Project entity.

In AbstractEntity I want to automatically inject Symfony\Component\Security\Core\Security service.

BUT the autowire stuff just doesn't work.

# config/services.yaml
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/' # --> i removed that line (doesnt work)
            - '../src/Kernel.php'

    #this also does not work
    App\Entity\AbstractEntity:
        autowire: true

    #this also does not work
    App\Entity\AbstractEntity:
        arguments:
            - '@security.helper'
// src/Entity/AbstractEntity.php
<?php 

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Security;

#[ORM\MappedSuperclass]
#[ORM\HasLifecycleCallbacks]
abstract class AbstractEntity
{
    private $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }
}

CodePudding user response:

The entity should not have any dependencies and contain logic. If you want to do something, consider creating Doctrine Lifecycle Listeners prePersist or Doctrine Entity Listeners.


Lifecycle listeners are defined as PHP classes that listen to a single Doctrine event on all the application entities.


Add to services.yaml file

App\EventListener\CreatedByLifecycleEvent:
    tags:
        -
            name: 'doctrine.event_listener'
            event: 'prePersist'

And create a listener

namespace App\EventListener;
 
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Security;

class CreatedByLifecycleEvent
{
    private $security;
    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    public function prePersist(LifecycleEventArgs $args): void
    {
        $entity = $args->getObject();
        if(method_exists($entity,'setCreatedBy') and !empty($user = $this->security->getUser())){
            $entity->setCreatedBy($user);
        }
    } 
}

Thus, when saving any entity, provided that the setCreatedBy method exists, our listener will set the current user.

  • Related