@@ -78,3 +78,62 @@ $attribute_instances = get_attributes($reflection_function, MyReflectorAwareAttr
7878assert($attribute_instances[0] instanceof MyReflectorAwareAttribute);
7979assert($attribute_instances[0]->reflector === $reflection_function);
8080```
81+
82+ ### Using AttributeReader.
83+
84+ The AttributeReader class allows to support attribute types that do not use the mechanisms from this package.
85+
86+ Assume you have an attribute class like this, coming from a 3rd party package:
87+
88+ ``` php
89+ #[\Attribute(\Attribute::TARGET_CLASS)]
90+ class ThirdPartyAttribute {
91+ public readonly \Reflector $reflector;
92+ }
93+ ```
94+
95+ You can create a custom instantiator that will populate the property.
96+
97+ Ideally this should use the decorator pattern, so that multiple operations can be applied.
98+
99+ ``` php
100+ use Ock\ReflectorAwareAttributes\Instantiator\AttributeInstantiatorInterface;
101+ use Ock\ReflectorAwareAttributes\Reader\AttributeReader;
102+
103+ class MyInstantiator implements AttributeInstantiatorInterface {
104+
105+ public function __construct(
106+ private readonly AttributeInstantiatorInterface $decorated,
107+ ) {}
108+
109+ public function newInstance(
110+ \ReflectionAttribute $attribute,
111+ \ReflectionClassConstant|\ReflectionParameter|\ReflectionClass|\ReflectionProperty|\ReflectionFunctionAbstract $reflector,
112+ ): object {
113+ $instance = $this->decorated->newInstance($attribute, $reflector);
114+ if ($instance instanceof ThirdPartyAttribute) {
115+ $instance->reflector = $reflector;
116+ }
117+ return $instance;
118+ }
119+
120+ }
121+ ```
122+
123+ Now we can use a reader with this instantiator decorator to get the attribute instances.
124+
125+ ``` php
126+ #[ThirdPartyAttribute]
127+ class C {}
128+
129+ $reader = AttributeReader::basic()
130+ ->withDecoratingInstantiator(
131+ fn (AttributeInstantiatorInterface $decorated) => new MyInstantiator($decorated),
132+ );
133+
134+ $reflection_class = new \ReflectionClass(C::class);
135+ $instances = $reader->getInstances($reflection_class, ThirdPartyAttribute::class);
136+
137+ assert($instances[0] instanceof ThirdPartyAttribute);
138+ assert($instances[0]->reflector === $reflection_class);
139+ ```
0 commit comments