Skip to content

Commit 2f8db00

Browse files
committed
Adjust private properties writeup, move it
1 parent 8189ba7 commit 2f8db00

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

guide/en/concept/di-container.md

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,6 @@ final readonly class CachedWidget
6868
We've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache
6969
implementation without changing `CachedWidget` so it's becoming more stable.
7070

71-
### Why use private properties <span id="why-private-properties"></span>
72-
73-
In the composition example above, note that the `$cache` property is declared as `private`. This design choice
74-
supports composition by providing several benefits:
75-
76-
- **Encapsulation**: Private properties with getters/setters allow you to control access and make future changes
77-
without breaking existing code.
78-
- **Data integrity**: Setters can validate, normalize, or format values before storing them, ensuring properties
79-
contain valid data.
80-
- **Immutability**: Private properties enable immutable object patterns where setters return new instances rather
81-
than modifying the current one.
82-
- **Flexibility**: You can easily create read-only or write-only properties, or add additional logic to property
83-
access later.
84-
85-
This approach embraces composition by ensuring objects have well-defined interfaces for interaction rather than
86-
direct property access, making the code more maintainable and less prone to certain types of mistakes.
87-
8871
The `CacheInterface` here is a dependency: an object another object depends on.
8972
The process of putting an instance of dependency into an object (`CachedWidget`) is called dependency injection.
9073
There are many ways to perform it:
@@ -93,21 +76,38 @@ There are many ways to perform it:
9376
- Method injection. Best for optional dependencies.
9477
- Property injection. Better to be avoided in PHP except maybe data transfer objects.
9578

79+
### Why use private properties <span id="why-private-properties"></span>
80+
81+
In the composition example above, note that the `$cache` property is declared as `private`.
82+
83+
This approach embraces composition by ensuring objects have well-defined interfaces for interaction rather than
84+
direct property access, making the code more maintainable and less prone to certain types of mistakes.
85+
86+
This design choice provides several benefits:
87+
88+
- **Encapsulation**: Private properties with getters/setters allow you to control access and make future changes
89+
without breaking existing code.
90+
- **Data integrity**: Setters can validate, normalize, or format values before storing them, ensuring properties
91+
contain valid data.
92+
- **Immutability**: Private properties enable immutable object patterns where setter `with*()` methods return
93+
new instances rather than modifying the current one.
94+
- **Flexibility**: You can create read-only or write-only properties or add additional logic to property access later.
95+
9696

9797
## DI container <span id="di-container"></span>
9898

99-
Injecting basic dependencies is simple and easy. You're choosing a place where you don't care about dependencies,
99+
Injecting basic dependencies is straightforward. You're choosing a place where you don't care about dependencies,
100100
which is usually an action handler, which you aren't going to unit-test ever, create instances of dependencies needed
101101
and pass these to dependent classes.
102102

103-
It works well when there aren't many dependencies overall and when there are no nested dependencies. When there are
103+
It works well when there are few dependencies overall and when there are no nested dependencies. When there are
104104
many and each dependency has dependencies itself, instantiating the whole hierarchy becomes a tedious process, which
105-
requires lots of code and may lead to hard to debug mistakes.
105+
requires lots of code and may lead to hardly debuggable mistakes.
106106

107-
Additionally, lots of dependencies, such as certain third party API wrapper, are the same for any class using it.
107+
Additionally, lots of dependencies, such as certain third-party API wrappers, are the same for any class using it.
108108
So it makes sense to:
109109

110-
- Define how to instantiate such API wrapper once.
110+
- Define how to instantiate such an API wrapper.
111111
- Instantiate it when required and only once per request.
112112

113113
That's what dependency containers are for.
@@ -187,9 +187,10 @@ return [
187187

188188
### Injecting dependencies <span id="injecting-dependencies"></span>
189189

190-
Directly referencing container in a class is a bad idea since the code becomes non-generic, coupled to container interface
191-
and, what's worse, dependencies are becoming hidden. Because of that, Yii inverts the control by automatically injecting
192-
objects from a container in some constructors and methods based on method argument types.
190+
Directly referencing a container in a class is a bad idea since the code becomes non-generic,
191+
coupled to the container interface and, what's worse, dependencies are becoming hidden.
192+
Because of that, Yii inverts the control by automatically injecting objects from a container in some constructors
193+
and methods based on method argument types.
193194

194195
This is primarily done in constructor and handing method of action handlers:
195196

@@ -219,9 +220,9 @@ final readonly class MyController
219220
```
220221

221222
Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that instantiates and calls action handler, it
222-
checks the constructor and method argument types, get dependencies of these types from a container and pass them as
223+
checks the constructor and method argument types, gets dependencies of these types from a container and passes them as
223224
arguments. That's usually called auto-wiring. It happens for sub-dependencies as well, that's if you don't give dependency
224-
explicitly, container would check if it has such a dependency first.
225+
explicitly, the container would check if it has such a dependency first.
225226
It's enough to declare a dependency you need, and it would be got from a container automatically.
226227

227228

0 commit comments

Comments
 (0)