Skip to content

Type based injection

that-depends also supports dependency injection without explicitly referencing the provider of the dependency.

Quick Start

In order to make use of this, you need to bind providers to the type they will provide:

class Container(BaseContainer):
    my_provider = providers.Factory(lambda: random.random()).bind(float)

Then provide inject into your functions or generators:

@Container.inject
async def foo(v: float = Provide()):
    return v
@inject(container=Container)
async def foo(v: float = Provide()):
    return v

Default bind

Per default, providers will not be bound to any type, even if your creator function has type hints. So make sure to always bind your providers.

You can also bind multiple types to the same provider:

class Container(BaseContainer):
    my_provider = providers.Factory(lambda: random.random()).bind(float, complex)

Contravariant binding

Per default injection will be invariant to the bound types.

If you wish to enable contravariance for your bound types you can do so by setting contravariant=True in the bind method:

class A: ...

class B(A): ...

class Container(BaseContainer):
    my_provider = providers.Factory(lambda: B()).bind(B, contravariant=True)

@Container.inject
async def foo(v: A = Provide()) -> A: # (1)!
    return v
  1. v will receive an instance of B since A is a supertype of B.