Skip to content

Commit e6ba3a9

Browse files
committed
Rewords
1 parent dfafe24 commit e6ba3a9

File tree

2 files changed

+48
-47
lines changed

2 files changed

+48
-47
lines changed

doctrine.rst

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -789,22 +789,26 @@ variable. Let's say you want the first or the last comment of a product dependin
789789
Fetch via Interfaces
790790
~~~~~~~~~~~~~~~~~~~~
791791

792-
Suppose your ``Product`` object implements an interface called ``ProductInterface``.
793-
If you want to decouple your controllers from your entity implementations, you can instead reference entities via an interface.
794-
To do this, first you need to configure the :doc:`resolve_target_entities option </doctrine/resolve_target_entity>`.
795-
796-
Your controller can then reference the Product entity by its interface instead::
792+
Suppose your ``Product`` class implements an interface called ``ProductInterface``.
793+
If you want to decouple your controllers from the concrete entity implementation,
794+
you can reference the entity by its interface instead.
797795

798-
public function show(
799-
#[MapEntity]
800-
ProductInterface $product
801-
): Response {
802-
// ...
803-
}
796+
To enable this, first configure the
797+
:doc:`resolve_target_entities option </doctrine/resolve_target_entity>`.
798+
Then, your controller can type-hint the interface, and the entity will be
799+
resolved automatically::
800+
801+
public function show(
802+
#[MapEntity]
803+
ProductInterface $product
804+
): Response {
805+
// ...
806+
}
804807
805808
.. versionadded:: 7.3
806809

807-
Support for ``resolve_target_entites`` in the ``EntityValueResolver`` was introduced in Symfony 7.3.
810+
Support for target entity resolution in the ``EntityValueResolver`` was
811+
introduced Symfony 7.3
808812

809813
MapEntity Options
810814
~~~~~~~~~~~~~~~~~

doctrine/resolve_target_entity.rst

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,45 @@
11
Referencing Entities with Abstract Classes and Interfaces
22
=========================================================
33

4-
In applications where functionality is segregated with minimal concrete dependencies
5-
between the various layers, such as monoliths which are split into multiple modules,
6-
it might be hard to prevent hard dependencies on entities between modules.
4+
In applications where functionality is organized in layers or modules with
5+
minimal concrete dependencies, such as monoliths split into multiple modules,
6+
it can be challenging to avoid tight coupling between entities.
77

8-
Doctrine 2.2 includes a new utility called the ``ResolveTargetEntityListener``,
9-
that functions by intercepting certain calls inside Doctrine and rewriting
10-
``targetEntity`` parameters in your metadata mapping at runtime. It means that
11-
you are able to use an interface or abstract class in your mappings and expect
12-
correct mapping to a concrete entity at runtime.
8+
Doctrine provides a utility called the ``ResolveTargetEntityListener`` to solve
9+
this issue. It works by intercepting certain calls within Doctrine and rewriting
10+
``targetEntity`` parameters in your metadata mapping at runtime. This allows you
11+
to reference an interface or abstract class in your mappings and have it resolved
12+
to a concrete entity at runtime.
1313

14-
This functionality allows you to define relationships between different entities
15-
without making them hard dependencies.
14+
This makes it possible to define relationships between entities without
15+
creating hard dependencies. This feature also works with the ``EntityValueResolver``
16+
:ref:`as explained in the main Doctrine article <doctrine-entity-value-resolver-resolve-target-entities>`.
1617

17-
.. tip::
18+
.. versionadded:: 7.3
1819

19-
Starting with Symfony 7.3, this functionality also works with the ``EntityValueResolver``.
20-
See :ref:`doctrine-entity-value-resolver-resolve-target-entities` for more details.
20+
Support for target entity resolution in the ``EntityValueResolver`` was
21+
introduced Symfony 7.3
2122

2223
Background
2324
----------
2425

25-
Suppose you have an application which provides two modules; an Invoice module which
26-
provides invoicing functionality, and a Customer module that contains customer management
27-
tools. You want to keep dependencies between these modules separated, because they should
28-
not be aware of the other module's implementation details.
26+
Suppose you have an application with two modules: an Invoice module that
27+
provides invoicing functionality, and a Customer module that handles customer
28+
management. You want to keep these modules decoupled, so that neither is aware
29+
of the other's implementation details.
2930

30-
In this case, you have an ``Invoice`` entity with a relationship to the interface
31-
``InvoiceSubjectInterface``. This is not recognized as a valid entity by Doctrine.
32-
The goal is to get the ``ResolveTargetEntityListener`` to replace any mention of the interface
33-
with a real object that implements that interface.
31+
In this case, your ``Invoice`` entity has a relationship to the interface
32+
``InvoiceSubjectInterface``. Since interfaces are not valid Doctrine entities,
33+
the goal is to use the ``ResolveTargetEntityListener`` to replace all
34+
references to this interface with a concrete class that implements it.
3435

3536
Set up
3637
------
3738

38-
This article uses the following two basic entities (which are incomplete for
39-
brevity) to explain how to set up and use the ``ResolveTargetEntityListener``.
39+
This article uses two basic (incomplete) entities to demonstrate how to set up
40+
and use the ``ResolveTargetEntityListener``.
4041

41-
A Customer entity::
42+
A ``Customer`` entity::
4243

4344
// src/Entity/Customer.php
4445
namespace App\Entity;
@@ -55,17 +56,14 @@ A Customer entity::
5556
// are already implemented in the BaseCustomer
5657
}
5758

58-
An Invoice entity::
59+
An ``Invoice`` entity::
5960

6061
// src/Entity/Invoice.php
6162
namespace App\Entity;
6263

6364
use App\Model\InvoiceSubjectInterface;
6465
use Doctrine\ORM\Mapping as ORM;
6566

66-
/**
67-
* Represents an Invoice.
68-
*/
6967
#[ORM\Entity]
7068
#[ORM\Table(name: 'invoice')]
7169
class Invoice
@@ -74,7 +72,7 @@ An Invoice entity::
7472
protected InvoiceSubjectInterface $subject;
7573
}
7674

77-
An InvoiceSubjectInterface::
75+
The interface representing the subject used in the invoice::
7876

7977
// src/Model/InvoiceSubjectInterface.php
8078
namespace App\Model;
@@ -94,8 +92,8 @@ An InvoiceSubjectInterface::
9492
public function getName(): string;
9593
}
9694

97-
Next, you need to configure the ``resolve_target_entities`` option, which tells the DoctrineBundle
98-
about the replacement:
95+
Now configure the ``resolve_target_entities`` option to tell Doctrine
96+
how to replace the interface with the concrete class:
9997

10098
.. configuration-block::
10199

@@ -145,7 +143,6 @@ about the replacement:
145143
Final Thoughts
146144
--------------
147145

148-
With the ``ResolveTargetEntityListener``, you are able to decouple your
149-
modules, keeping them usable by themselves, but still being able to
150-
define relationships between different objects. By using this method,
151-
your modules will end up being easier to maintain independently.
146+
Using ``ResolveTargetEntityListener`` allows you to decouple your modules
147+
while still defining relationships between their entities. This makes your
148+
codebase more modular and easier to maintain over time.

0 commit comments

Comments
 (0)