-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic dependencies #9
Comments
Need to add a way to understand what dependencies can be accessed during dynamic selection |
import abc
import asyncio
from dishka import Provider, provide, Scope, make_async_container
class DepMeta(abc.ABCMeta):
registered_deps: list[type] = []
def __new__(mcs, *args, **kwargs) -> type:
dep_class = super().__new__(mcs, *args, **kwargs)
DepMeta.registered_deps.append(dep_class)
return dep_class
class AbstractDep(metaclass=DepMeta):
def __init__(self):
self.dep_id = id(self)
def __str__(self) -> str:
return f'{self.__class__.__name__}({self.dep_id})'
class Dependency1(AbstractDep):
...
class Dependency2(AbstractDep):
...
class Dependency3(AbstractDep):
...
class MyProvider(Provider):
def __init__(self, scope=None):
super().__init__(scope)
for dep in DepMeta.registered_deps:
setattr(self, str(dep.__name__), provide(dep, scope=Scope.REQUEST))
self._init_dependency_sources()
async def main():
async with make_async_container(MyProvider()) as app_container:
async with app_container() as container:
print(await container.get(Dependency1))
print(await container.get(Dependency2))
print(await container.get(Dependency3))
async with app_container() as container:
print(await container.get(Dependency1))
print(await container.get(Dependency2))
print(await container.get(Dependency3))
if __name__ == '__main__':
asyncio.run(main()) Right now the only way is do some like that. It may be very useful for automated dependencies registration, such Repositories, Services that collected in AbstractRegistryMetadata etc. |
Version 0.4.0 released |
Absolutely amazing. |
As an Idea for dynamic dependencies: dynamic alias @alias(provides=MyProto)
def foo(self, request: Request) -> Type[TypeA] | Type[TypeB]:
if ...:
return TypeA
else:
return TypeB It will work the same as: @provide
def foo(self, request: Request, container: Container) -> MyProto:
if ...:
return container.get(TypeA)
else:
return container.get(TypeB) We can use return type annotations for graph validation |
Another idea: @provide
def xxx(self, a: Deferred[XxxA], b: Deferred[XxxB], r: Request) -> XxxProto:
if r.something:
return a.ensure()
else:
return b.ensure() |
Create something depending on, at least, request data
The text was updated successfully, but these errors were encountered: