Skip to content
Blog

Stubbing in Python met Dependency Injector

fieldside-admin
fieldside-admin
Geschreven op 10 Mar 2026
3 min leestijd
Technologie

Bij één van onze klanten werd gestart met het opsplitsen van enkele monolithische applicaties naar REST-gebaseerde microservices.<br/><br/>Voor een eerste use case werden enkele belangrijke services geïdentificeerd, waaronder een aggregatorservice. Deze service fungeert eigenlijk als een laag die drie andere microservices samenbrengt.<br/><br/>In deze blog bekijken we: Hoe dependency injection in Python opgezet kan worden met Dependency Injector,<br/>En hoe deze dependencies dynamisch gestubd kunnen worden op basis van de omgeving.

Het probleem

Het doel was om deze eerste microservice zo snel mogelijk op te leveren, zonder in te boeten op codekwaliteit. Zo konden de architecturale en technische keuzes meteen gevalideerd worden.

Na een eerste analysefase werden OpenAPI-specificaties opgesteld voor vier microservices, waarna de ontwikkeling van alle services gelijktijdig werd opgestart.

De developer die werkte aan de aggregatorservice was echter afhankelijk van de drie andere services. Om te vermijden dat de ontwikkeling geblokkeerd werd doordat die services nog niet bestonden, werd gekozen om deze services tijdelijk te stubben.

De oplossing

Opmerking: in dit voorbeeld wordt FastAPI gebruikt, maar de aanpak is framework-onafhankelijk.

In dit voorbeeld bouwen we een service die basisinformatie over bedrijven teruggeeft, samen met de werknemers die voor dat bedrijf werken.

De bedrijfs- en werknemersdata komen uit externe services, zoals:
· andere microservices,
· database calls,
· events,
· of andere databronnen.

De starterapplicatie is terug te vinden in de main van deze start https://github.com/wimvdc/dependency_injection

De uiteindelijke oplossing staat in de main branch.

Voor dependency injection wordt gebruikgemaakt van Dependency Injector, een dependency injection framework voor Python.

1. Stub classes aanmaken

To start, we created a stub class for both company and employee services.

De eerste stap bestaat uit het aanmaken van een stubklasse voor zowel de company service als de employee service.

Deze stubklassen zijn in essentie kopieën van de originele classes, inclusief dezelfde methodesignatures.

Daardoor kan eenvoudig gewisseld worden tussen de echte implementatie en de stubversie zonder aanpassingen aan de rest van de codebase.

2. Container configureren

Vervolgens wordt een container.py binnen de data. Deze container is verantwoordelijk voor het samenstellen van alle dependencies binnen deze laag.

Hier komt Dependency Injector echt in beeld.

De container functioneert als een declaratieve verzameling van providers:
· providers creëren objecten,
· en injecteren automatisch de juiste dependencies.

In dit voorbeeld wordt een singleton provider gebruikt, maar Dependency Injector ondersteunt ook andere patronen zoals:
· Factory,
· Coroutine,
· en verschillende andere providertypes.

3. Wiring voorzien

De volgende stap is het koppelen van de container aan de endpoint of route die de dependency effectief gebruikt.
Hierbij wordt aan de container doorgegeven in welke modules of packages dependency injection beschikbaar moet zijn.

In dit voorbeeld gebeurt dat binnen de application module.

4. Dependencies injecteren

De effectieve dependency injection gebeurt via de @inject.
Daarnaast wordt via de provider uit de container aangegeven welke dependency geïnjecteerd moet worden.

Na deze stap is dependency injection volledig opgezet en kan de applicatie gestart worden.

Door de configuratie binnen de container aan te passen, kan eenvoudig gekozen worden tussen de echte implementatie of de stubversie van een service.

5. Dynamische injection

Het voortdurend aanpassen van container.py om dependencies te wisselen is uiteraard niet ideaal. container.py
Daarom wordt de container uitgebreid, zodat configuratie uit een extern configuratiebestand gelezen kan worden. Hiervoor wordt een injection.json bestand toegevoegd binnen een nieuwe config folder in de root van het project.

Door deze aanpak kan configuratie aangepast worden zonder codewijzigingen. Bovendien maakt dit omgevingsspecifieke configuratie mogelijk.configinjection.json

In de laatste stap wordt container.py aangepast, zodat:
· het configuratiebestand ingelezen wordt,
· en bepaalde providers overschreven kunnen worden wanneer nodig.

In dit voorbeeld wordt:
· de gestubde versie van de company service gebruikt,
· terwijl voor de employee service de echte implementatie actief blijft.injection.json

< Keep reading />

More from our team

Explore more insights, tips, and deep dives from the CraftCode team.

TDD voor leesbare code
Blog </> · 3 min leestijd

TDD voor leesbare code

Blog </> · 2 min leestijd

End-to-end tracing: krijg grip op de chaos van microservices!

Blog </> · 3 min leestijd

Repetitieve code wegwerken met een vaak vergeten annotatie

Blog </> · 3 min leestijd

De Apache Camel Experience

Aan de slag!

Klaar om jouw visie werkelijkheid te maken?
Laten we iets bouwen waar je bedrijf écht mee verder kan.