Search code examples
phpsymfonydependency-injectionsymfony4symfony-4.3

Dependency-Injection of an Doctrine-Entity into a Service in Symfony4?


I'm trying to inject an Entity via DI into a service.

The Entity is created from a JSON-Field in the database (which got queried from the user-request) via the Doctrine-JSON-ODM-library (https://github.com/dunglas/doctrine-json-odm).

I would generally write a Context-class, which would take Request & Repository to return the Dependency( as described here https://blogs.cuttingedge.it/steven/posts/2015/code-smell-injecting-runtime-data-into-components/ ). However since my dependencies rely on deeply nested data inside a tree-structure, this does not seem feasible.

/* Doctrine-Entity queried from DB with User-Request-Parameters */
class Page
{
    /**
     * @var Slot[]
     * @ORM\Column(type="json_document", options={"jsonb": true})
     */
    private $slots = [];
}

/* First level of nesting */
class Slot
{
    /** @var Components[] */
    private $components;
}

/* Entity to be injected */
class Component
{
   // multiple data-fields
}

// Service which will need to work with the Component-Data
class ComponentRenderService
{
   // multiple functions which all need (read)-access to the
   // Component-data
}

How can I resolve a dependency which get's created via a deeply nested-structure?


Solution

  • Adding to my comment on original post, once you pass the entity as method argument, you can set it as class variable, i.e.:

    $service->method($entity)

    class Service 
    {
    
        private $entity;
    
        public function method($entity) // You call this somewhere
        {
           // If I understood you correctly, this is what you need
           $this->entity = $entity; // You set it as a class variable (same as DI does in constructor)
    
           // do stuff to $this->entity
        }
    
    
       public function otherMethod()
       {
          // you can access $this->entity here provided that you called `method` first
       }
    
    }