Utilisation d'un framework d'injection de dépendances #40
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Comme annoncé par #37, #38, #39, les nouvelles PRs ont montré des besoins particuliers et nous nous devons d'y répondre. Jusque-là, le design s'appuyait sur un certains nombres de classes et des accès génériques pour avoir de la souplesse. Le problème est que la construction même de ces liens de dépendances nous forçait à faire un parcours qui n'est pas souhaité quand, disons, il n'y a pas d'Entité, ou encore lorsque les dépendances des objets sont exotiques, comme il vient d'arriver sur ces dernières PRs.
Depuis longtemps, on sait que si nous voulons bien tester notre applicatif en isolation, l'injection de dépendance est imparable – on injecte un objet dans un autre et dans le test on simule ce dernier.
Cependant dans notre code, si nous voulons bien former nos contrats, on peut rapidement avoir une chaîne monstre de dépendances à charger pour satisfaire l'objet X, et c'est là que les frameworks d'injection de dépendances entrent en scène. Ils permettent de comprendre tous seuls de quoi l'objet a besoin et lui fournissent automatiquement. L'effet pervers parfois est un design désastreux, mais je ne transigerai pas sur ce point, il est possible de faire les choses bien.
À terme, il nous suffira de demander un objet, disons
PlanningController
, et le framework se chargera de charger le repo qui va bien, le router, la DAO. Bref, tous les injectables qui ont été conçus en dépendances de l'objet voulu. Je rappelle qu'il y a une séparation stricte entre injectable et newable et il est vital de la comprendre pour utiliser le DIF, dans le cas contraire, il ne marchera pas.Donc, notre framework,
Slim
possédait déjà un tel gestionnaire, mais il lui manque une fonctionnalité clé ; j'ai donc misphp-di
que je connais bien.Le moins qu'on puisse dire c'est que j'en ai bavé. Le bridge était une fausse bonne idée (le Resolver de route change 😱 !) et il me fallait viser la compatibilité. Mais j'ai réussi.
Pour le moment
J'ai réussi à rendre le DIF compatible avec l'existant, à la fois pour ne rien casser et pour éviter une PR de 10kLOC. Il n'est donc pas à sa pleine puissance, puisque le but n'était pas là.
Futur
Comme je l'ai dit plus haut, c'est un outil qui nous facilite certaines tâches. À l'avenir, le DIF remplacera le ControllerFactory que je n'ai jamais vraiment aimé et toutes les routes seront plus précises (ex :
+ $this->get('', [PlanningController::class, 'get'])
) pour que le Resolver puisse bosser. Nous pourrons alors ajouter des services lorsque l'API contiendra du métier. La PR suivante s'occupera donc de faire ça, corriger les soucis de dépendances qui adviendront et remettre des PRs précédentes sur les rails.