Skip to content

Commit 5cc3ab2

Browse files
committed
feat: Implement delegate method for custom instantiation #13
1 parent 97e6c27 commit 5cc3ab2

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,37 @@ $injector->valueFinder->onLookup(function (string $name, string $typeName, bool
9898
});
9999
```
100100

101+
### Delegating Class Instantiation
102+
103+
For classes requiring specific instantiation logic, the `DependencyInjector` offers a `delegate` method. This method allows you to specify a custom callback for creating instances of a specific class, providing greater control over the object creation process.
104+
105+
```php
106+
<?php
107+
108+
require_once 'vendor/autoload.php';
109+
110+
use CommonPHP\DependencyInjection\DependencyInjector;
111+
112+
class SpecificClass {
113+
private string $customArg1;
114+
private string $customArg2;
115+
116+
public function __construct(string $customArg1, string $customArg2) {
117+
// Custom construction logic here
118+
}
119+
}
120+
121+
$injector = new DependencyInjector();
122+
123+
// Delegate instantiation of SpecificClass to a custom callback
124+
$injector->delegate(SpecificClass::class, function($injector, $name, $typeName) {
125+
return new SpecificClass('value1', 'value2');
126+
});
127+
128+
// Automatically use the delegate when SpecificClass is needed
129+
$instance = $injector->instantiate(InitiatedClass::class);
130+
```
131+
101132
## Documentation
102133

103134
For more in-depth documentation, check out [the Wiki](https://github.com/commonphp/di/wiki).

examples/delegate.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
require_once '../vendor/autoload.php';
4+
5+
use CommonPHP\DependencyInjection\DependencyInjector;
6+
7+
// Assuming SpecificClass requires custom instantiation logic
8+
class SpecificClass
9+
{
10+
private string $customArg1;
11+
private string $customArg2;
12+
public function __construct(string $customArg1, string $customArg2)
13+
{
14+
$this->customArg1 = $customArg1;
15+
$this->customArg2 = $customArg2;
16+
// Custom construction logic here
17+
}
18+
}
19+
20+
class InitiatedClass
21+
{
22+
private SpecificClass $specificClass;
23+
public function __construct(SpecificClass $specificClass)
24+
{
25+
$this->specificClass = $specificClass;
26+
}
27+
}
28+
29+
$injector = new DependencyInjector();
30+
31+
// Delegate the instantiation of SpecificClass to a custom callback
32+
$injector->delegate(SpecificClass::class, function($injector, $name, $typeName) {
33+
// Example of using custom arguments
34+
$customArg1 = 'value1';
35+
$customArg2 = 'value2';
36+
37+
return new SpecificClass($customArg1, $customArg2);
38+
});
39+
40+
// Instantiate SpecificClass using the custom delegate logic
41+
$instance = $injector->instantiate(InitiatedClass::class, []);
42+
43+
// Demonstrates that the $instance is indeed an object of SpecificClass
44+
var_dump($instance);

src/DependencyInjector.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use CommonPHP\DependencyInjection\Exceptions\MethodNotDefinedException;
2626
use CommonPHP\DependencyInjection\Exceptions\MethodNotPublicException;
2727
use CommonPHP\DependencyInjection\Exceptions\ParameterDiscoveryFailedException;
28+
use CommonPHP\DependencyInjection\Exceptions\ParameterTypeRequiredException;
2829
use CommonPHP\DependencyInjection\Exceptions\UnsupportedReflectionTypeException;
2930
use CommonPHP\DependencyInjection\Support\ValueFinder;
3031
use CommonPHP\DependencyInjection\Support\InstantiationStack;
@@ -50,6 +51,32 @@ public function __construct()
5051
$this->valueFinder = new ValueFinder();
5152
}
5253

54+
/**
55+
* Assigns a custom callback for instantiating a specified class.
56+
*
57+
* Enables defining a custom instantiation logic for a specific class through a callback,
58+
* thereby overriding the default instantiation mechanism. This feature is particularly useful
59+
* for setting up complex objects or integrating classes requiring specific construction patterns,
60+
* enhancing flexibility in object creation within the dependency injection system.
61+
*
62+
* @param string $className The fully qualified name of the class for custom instantiation.
63+
* @param callable $callback A user-defined function that instantiates the class. The callback
64+
* is provided with the DependencyInjector instance, class name,
65+
* and type name, facilitating context-aware instantiation.
66+
* @return void
67+
*/
68+
public function delegate(string $className, callable $callback): void
69+
{
70+
$this->valueFinder->onLookup(function ($name, $typeName, &$found) use ($className, $callback) {
71+
var_dump($typeName, $className);
72+
if ($typeName === $className) {
73+
$found = true;
74+
return $callback($this, $name, $typeName);
75+
}
76+
return null;
77+
});
78+
}
79+
5380
/**
5481
* Instantiates a class with the given parameters, resolving dependencies automatically.
5582
*
@@ -63,6 +90,7 @@ public function __construct()
6390
* @throws UnsupportedReflectionTypeException
6491
* @throws InstantiateCircularReferenceException
6592
* @throws InstantiationFailedException
93+
* @throws ParameterTypeRequiredException
6694
*/
6795
public function instantiate(string $className, array $parameters): object
6896
{

0 commit comments

Comments
 (0)