Northwoods Entity Proxy
, (*1)
A reflection based proxy for hydrating objects with private properties., (*2)
Attempts to be PSR-1, PSR-2, and PSR-4 compliant., (*3)
Install
composer require northwoods/entity-proxy
Usage
Proxies are created with the singleton ProxyFactory
:, (*4)
use Northwoods\EntityProxy\ProxyFactory;
Proxies can be created as wrappers around existing objects:, (*5)
$proxy = ProxyFactory::modify($user);
$proxy->set('email', 'user@example.com');
Or new instances when hydrating from other data sources:, (*6)
$proxy = ProxyFactory::create(User::class);
$proxy->setArray([
'id' => 1234,
'username' => 'jane.doe',
'email' => null,
]);
/** @var User */
$user = $proxy->reveal();
Proxies can also read existing values on the object:, (*7)
$username = $proxy->get('username');
Reasoning
In Domain Driven Design it is often recommended that entities use private
properties with getters to access state and setters to change state based on
business requirements. Since an entity is considered to be a persistent object,
its constructor should only be called once for the lifetime of the entity.
This allows for domain events to be triggered by the constructor to notify the
application that, for example, a new user has registered., (*8)
With this limitation in mind, the requirements for the hydrator are:, (*9)
- It must not call the entity constructor.
- It must be able to set private/protected properties.
- It must be as efficient as possible.
The easiest way to achieve these goals is to use reflection, which allows us to
create objects without constuctor, make properties accessible,
and write property values. The reflection of every class should be
internally cached for the lifetime of the factory to maximize performance., (*10)
If performance is of concern there are other viable approaches
that are faster but more complicated to setup and use., (*11)
License
MIT, (*12)