|
1 | | -# CommonPHP Dependency Injection Library |
| 1 | +# CommonPHP Dependency Injection |
2 | 2 |
|
3 | | -This library provides a straightforward way to manage service dependencies in a PHP application. It follows the Inversion of Control principle, allowing classes to specify their dependencies without being responsible for their creation. |
| 3 | +`CommonPHP\DependencyInjection` is a simple yet powerful dependency injection (DI) container for PHP applications, enabling the means to dynamically create new objects, invoke methods, call functions and populate properties without having to know the structure of the target directly. |
| 4 | + |
| 5 | +enabling automatic instantiation and wiring of your classes. It is part of the CommonPHP project, which offers various components to ease PHP development. |
4 | 6 |
|
5 | 7 | ## Features |
6 | 8 |
|
7 | | -1. **Dependency Injection**: Enables classes to declare their dependencies in the constructor, which will be automatically injected when the class is instantiated. |
| 9 | +- Constructor and method injection: Instantiate classes and invoke methods with automatic resolution of dependencies. |
| 10 | +- Value finder: A support class for the DI process that assists in discovering and managing parameter values during instantiation. |
| 11 | +- Handling of circular dependencies: An instantiation stack to prevent issues caused by recursive dependency chains. |
| 12 | +- Customizable parameter lookup: Enhance the default lookup process by adding custom lookup hooks. |
| 13 | +- Populating object properties: Assign values to an object's properties, handling a variety of visibility and type scenarios. |
| 14 | +- Exception handling: A series of specific exceptions to help troubleshoot issues related to DI and instantiation. |
| 15 | + |
| 16 | +## Requirements |
8 | 17 |
|
9 | | -2. **Service Container**: The library includes a service container that manages service instances. Services are created as singletons - once a service is created, the same instance will be returned every time it is requested. |
| 18 | +The CommonPHP framework requires PHP 8.1 or newer. This library specifically has the following dependencies: |
10 | 19 |
|
11 | | -3. **Simple API**: The library provides simple and intuitive methods for registering services and retrieving them from the service container. |
| 20 | +- PHP's built-in Reflection classes, which are used extensively for instantiating classes, invoking methods, and reading type information. |
12 | 21 |
|
13 | | -## Usage |
14 | 22 |
|
15 | | -Here is a simple example of how to use the library: |
| 23 | +## Installation |
| 24 | + |
| 25 | +You can install `CommonPHP\DependencyInjection` using Composer: |
| 26 | + |
| 27 | +```bash |
| 28 | +composer require comphp/di |
| 29 | +``` |
| 30 | + |
| 31 | +## Basic Usage |
| 32 | + |
| 33 | +### Instantiating Classes |
| 34 | + |
| 35 | +The main component is the `DependencyInjector` class, which is responsible for injecting the passed parameters into a constructor, method or function. |
16 | 36 |
|
17 | 37 | ```php |
18 | | -class MyClass { |
19 | | - public function __construct(CommonPHP\DependencyInjection\ServiceContainer $container) |
20 | | - { |
21 | | - // The service container is injected as a dependency |
22 | | - } |
23 | | -} |
| 38 | +<?php |
| 39 | + |
| 40 | +require_once 'vendor/autoload.php'; |
24 | 41 |
|
25 | | -$di = new CommonPHP\DependencyInjection\DependencyInjector(); |
26 | | -$container = new CommonPHP\DependencyInjection\ServiceContainer($di); |
| 42 | +use CommonPHP\DependencyInjection\DependencyInjector; |
27 | 43 |
|
28 | | -// Register your services |
29 | | -$di->services->register(MyClass::class); |
| 44 | +$injector = new DependencyInjector(); |
30 | 45 |
|
31 | | -// Retrieve the service |
32 | | -$myClassInstance = $container->get(MyClass::class); |
| 46 | +// Instantiate a class |
| 47 | +$exampleClass = $injector->instantiate(ExampleClass::class); |
| 48 | + |
| 49 | +// Invoke a method |
| 50 | +$result = $injector->invoke($exampleClass, 'exampleMethod'); |
| 51 | + |
| 52 | +// Call a function or closure |
| 53 | +$result = $injector->call('exampleFunction'); |
33 | 54 | ``` |
34 | 55 |
|
35 | | -This library is designed to prevent direct dependency on the `DependencyInjector` inside services. The `DependencyInjector` should only be used during application bootstrapping. |
| 56 | +### Populating Object Properties |
36 | 57 |
|
37 | | -## Installation |
| 58 | +The `DependencyInjector` can also populate the properties of an object: |
38 | 59 |
|
39 | | -This section outlines how to install the `CommonPHP Dependency Injection` library. |
| 60 | +```php |
| 61 | +<?php |
40 | 62 |
|
41 | | -### Requirements |
| 63 | +require_once 'vendor/autoload.php'; |
42 | 64 |
|
43 | | -- PHP 8.1 or newer. |
| 65 | +use CommonPHP\DependencyInjection\DependencyInjector; |
44 | 66 |
|
45 | | -### With Composer |
| 67 | +$injector = new DependencyInjector(); |
| 68 | +$object = new stdClass(); |
| 69 | +$values = ['property1' => 'value1', 'property2' => 'value2']; |
46 | 70 |
|
47 | | -The easiest way to install the `CommonPHP Dependency Injection` library is via Composer. |
| 71 | +// populate public properties only |
| 72 | +$injector->populate($object, $values); |
48 | 73 |
|
49 | | -If you don't have Composer installed, you can download it from [https://getcomposer.org/](https://getcomposer.org/). |
| 74 | +// populate all properties |
| 75 | +$injector->populate($object, $values, false); |
| 76 | +``` |
50 | 77 |
|
51 | | -Once you have Composer installed, you can install the `CommonPHP Dependency Injection` library by running the following command in your terminal: |
| 78 | +### Custom Lookup Hooks |
52 | 79 |
|
53 | | -```bash |
54 | | -composer require comphp/di |
| 80 | +The `ValueFinder` class allows you to add custom lookup hooks: |
| 81 | + |
| 82 | +```php |
| 83 | +<?php |
| 84 | + |
| 85 | +require_once 'vendor/autoload.php'; |
| 86 | + |
| 87 | +use CommonPHP\DependencyInjection\DependencyInjector; |
| 88 | + |
| 89 | +$injector = new DependencyInjector(); |
| 90 | + |
| 91 | +$injector->valueFinder->onLookup(function (string $name, string $typeName, bool &$found): mixed { |
| 92 | + if ($typeName == MyClassType::class) { |
| 93 | + $found = true; |
| 94 | + return new MyClassType(); |
| 95 | + } else if ($name == 'specificStringVariable') { |
| 96 | + $found = true; |
| 97 | + return 'specificStringValue'; |
| 98 | + } |
| 99 | + return null; |
| 100 | +}); |
55 | 101 | ``` |
56 | 102 |
|
57 | | -This command will add the `CommonPHP Dependency Injection` library as a dependency to your project, and Composer will automatically handle the autoloading of classes. |
| 103 | +## Documentation |
| 104 | + |
| 105 | +For more in-depth documentation, check out [the Wiki](https://github.com/commonphp/di/wiki). |
| 106 | + |
| 107 | +### API Reference |
| 108 | + |
| 109 | +This is a high-level overview of the API. For detailed information about classes, methods, and properties, please refer to the source code and accompanying PHPDoc comments. |
| 110 | + |
| 111 | +- **`CommonPHP\DependencyInjection\DependencyInjector`**: The main class in the library. Provides methods for instantiating classes, invoking methods, calling functions, and populating properties with automatic dependency resolution. |
| 112 | + |
| 113 | + - **`instantiate(string $class, array $params = []): object`**: Instantiates a class with the provided parameters. |
| 114 | + |
| 115 | + - **`invoke($object, string $method, array $params = [], bool $publicOnly = true): mixed`**: Invokes a method on a given object with the provided parameters. |
| 116 | + |
| 117 | + - **`call(callable $callable, array $params = []): mixed`**: Calls a function or closure with the provided parameters. |
| 118 | + |
| 119 | + - **`populate(object $object, array $values, bool $publicOnly = true): void`**: Populates the properties of an object with the given values. |
| 120 | + |
| 121 | +- **`CommonPHP\DependencyInjection\Support\ValueFinder`**: A supporting class that assists in discovering and managing parameter values during instantiation. |
| 122 | + |
| 123 | + - **`onLookup(callable $callback): void`**: Registers a callback function to be used during the lookup process. |
| 124 | + |
| 125 | +### Examples |
| 126 | + |
| 127 | +Here are some examples of using CommonPHP\DependencyInjection. You can find the full source code for these examples in the `examples` directory of this repository. |
58 | 128 |
|
59 | | -### Manual Installation |
| 129 | +- [**Instantiate**](https://github.com/commonphp/di/blob/master/examples/instantiate.php): This example shows how to instantiate a class using `DependencyInjector::instantiate()`. |
60 | 130 |
|
61 | | -If you don't use Composer, you can download the latest release of the `CommonPHP Dependency Injection` library from the GitHub repository. After downloading, you will have to handle autoloading the classes manually in your application. |
| 131 | +- [**Invoke**](https://github.com/commonphp/di/blob/master/examples/invoke.php): This example shows how to invoke a method using `DependencyInjector::invoke()`. |
62 | 132 |
|
63 | | -After the installation, you can use the library as outlined in the Usage section. |
| 133 | +- [**Call**](https://github.com/commonphp/di/blob/master/examples/call.php): This example shows how to call a function or closure using `DependencyInjector::call()`. |
64 | 134 |
|
65 | | -## Next Steps |
| 135 | +- [**Populate**](https://github.com/commonphp/di/blob/master/examples/populate.php): This example shows how to populate the properties of an object using `DependencyInjector::populate()`. |
66 | 136 |
|
67 | | -After the installation, refer to the Usage section of this README to learn how to use the `CommonPHP Dependency Injection` library in your projects. |
| 137 | +- [**Lookup Hooks**](https://github.com/commonphp/di/blob/master/examples/lookup-hooks.php): This example shows how to use a custom lookup hook with `ValueFinder::onLookup()`. |
| 138 | + |
| 139 | + |
| 140 | +## Contributing |
| 141 | + |
| 142 | +Contributions are always welcome! Please read the [contribution guidelines](CONTRIBUTING.md) first. |
68 | 143 |
|
69 | 144 | ## Testing |
70 | 145 |
|
71 | | -As of version 0.0.1, we are still in the process of refining the codebase and defining the overall functionality of the CommonPHP Dependency Injection library, as well as other libraries within the CommonPHP framework. Therefore, comprehensive unit tests have not been created yet. |
| 146 | +This project uses PHPUnit for unit testing. Follow the instructions below to run the tests: |
| 147 | + |
| 148 | +1. Ensure you have PHPUnit installed. If not, you can install it with Composer: |
| 149 | + |
| 150 | + ```bash |
| 151 | + composer require --dev phpunit/phpunit |
| 152 | + ``` |
| 153 | + |
| 154 | +2. Navigate to the project's root directory. |
| 155 | +
|
| 156 | +3. Run the tests using the following command: |
| 157 | +
|
| 158 | + ```bash |
| 159 | + ./vendor/bin/phpunit tests |
| 160 | + ``` |
| 161 | +
|
| 162 | +4. If the tests are successful, you will see output similar to: |
| 163 | +
|
| 164 | + ``` |
| 165 | + PHPUnit 9.6.9 by Sebastian Bergmann and contributors. |
| 166 | +
|
| 167 | + ...................... 22 / 22 (100%) |
| 168 | +
|
| 169 | + Time: 00:00.228, Memory: 4.00 MB |
72 | 170 |
|
73 | | -However, quality and reliability are paramount to us. Rest assured, we plan to incorporate robust testing in future versions as the functionality becomes more concrete. In the meantime, we encourage contributions in all areas of the project, including tests. |
| 171 | + OK (22 tests, 36 assertions) |
| 172 | + ``` |
74 | 173 |
|
75 | | -If you are interested in contributing to testing, or any other aspect of this project, please see the 'Contributing' section for more information. |
| 174 | +We recommend regularly running these tests during development to help catch any potential issues early. We also strive for a high level of test coverage, and additions to the codebase should ideally include corresponding tests. |
76 | 175 |
|
| 176 | +For more detailed output or for integration into continuous integration (CI) systems, PHPUnit can generate a log file in a variety of formats. Check the [PHPUnit documentation](https://phpunit.de/documentation.html) for more information. |
77 | 177 |
|
78 | 178 | ## License |
79 | 179 |
|
|
0 commit comments