-
Notifications
You must be signed in to change notification settings - Fork 0
Dependency Injection (Flask Injector)
With dependency injection, the method automagically receives instances of the classes it depends on. We don't want our upper layers worried about creating instances of classes/methods of the lower layers. By using dependency injection library, whenever the library sees a class it can inject into a method's parameter list, it automatically places an instance of the class into the parameter. A library for dependency injection is Flask Injector. An example may help demonstrate dependency injection.
Take for example the login method in auth.py:
@auth_api.route('/login', methods=['POST'])
@inject
def auth(auth_service: AuthenticationService):Here we use dependency injection to automagically insert an instance of AuthenticationService into the auth_service parameter. Flask Injector sees the inject annotation and examines the parameter list to find classes it can automagically inject in. Without dependency injection, we would need to create an instance of AuthenticationService. This makes to code longer to read and forces the upper layer to depend on the lower layer. This raises a question, how does Flask Injector know when/what to inject?
Flask Injector looks for the inject annotation to preform injection. When the API starts, we need to configure Flask Injector and tell it what each class maps to. This is done in configure method in dependencies.py.
def configure(binder):
binder.bind(AuthenticationService, to=PAMAuthenticationService, scope=singleton)The first argument in the bind method is the class Flask Injector looks for. The second argument is the class going to be injected in. The third argument is the scope for the dependency injection.