On Thu, Jul 3, 2025, at 12:54 PM, Andreas Hennings wrote:

>> > A setter method injection is what I did in AttributeUtils, because it was 
>> > the only real option.  Alternatively, I suppose core could use property 
>> > setter injection (either a magically named property like $__reflector, or 
>> > a property that itself has an attribute on it, etc.).  That would allow it 
>> > to be set before the constructor is called, and with property hooks would 
>> > allow processing either immediately or later in the constructor.  The 
>> > downside here is that Attribute are, generally, serializable, but a 
>> > Reflection object is not.  So if someone wanted a serializable attribute 
>> > they would have to accept the property, use it, and then remember to unset 
>> > it at some point.  That's clumsy.
>> >
>> > --Larry Garfield
>> >
>>
>> As someone that's written yet another userland "solution" for this problem, 
>> I have an alternative solution, based somewhat on an internalised  concept 
>> of "never store Reflectors".
>>
>> Introduce an interface "ReflectorAttribute" (bike shedding to come); which 
>> accepts a single Reflector argument.
>>
>> If the attribute implements the interface, the method is called immediately 
>> following instantiation.
>
> Yep, this is the "method injection" mentioned by Larry, or what I
> referred to as "setter injection".
> I have not seen your library, but I assume that's where it is going.

Yes, that is what AttributeUtils does today, almost exactly.  From the docs:

#[\Attribute]
class AttribWithName implements FromReflectionClass 
{
    public readonly string $name;
    
    public function __construct(?string $name = null) 
    {
        if ($name) {
            $this->name = $name;
        }
    }
    
    public function fromReflection(\ReflectionClass $subject): void
    {
        $this->name ??= $subject->getShortName();
    }
}

(There's a different interface for each type of thing an attribute can be put 
on because the parameter type is different.)

--Larry Garfield

Reply via email to