Closed givo closed 4 years ago
Hi!
In my opinion the whole point of DI is to be able to represent an application as a static graph of interconnected objects/services. That's why there are not scopes or dynamic binding. Static/immutable also leads to simple and cheap concurrency and thread-safety.
The idea to add asyncio
support seems logic. However, it will make the whole application graph async. This will lead to a partially initialized app graph. This will make thread-safety a very difficult problem to solve.
All in all, thanks for the idea. But it will dramatically complicate the injector.
Also, you can always fallback to something like this:
class Cache:
async def load():
pass
@inject.params(cache=Cache)
async def get_users(cache):
return await cache.load().get_users()
Hi!
First of all, thanks for your response.
I agree with your opinion of having a static graph and I understand the implications of adding asyncio support in the injector.
I think that today most of the applications are and going to be implemented using asyncio or similar framework. Therefore, developers may find it very useful to have an async DI framework, exactly like yours, that will create a static object graph asynchronously (only the creation).
My previous example wasn't representing a practical usage of this kind of feature. I'll just put here another example that hopefully emphasizes the idea.
import inject
from db_package import DatabaseClient
async def connect_to_db():
db_client = DatabaseClient('localhost', 4444)
await db_client.connect()
return db_client
def config(binder):
binder.bind_async('DB_CONNECTION', connect_to_db)
# you can even support running the coroutine on a specific event loop
loop = asyncio.get_event_loop()
binder.bind_async('DB_CONNECTION', connect_to_db, loop=loop)
inject.configure(config)
# dependency injection
class UsersService:
@inject.params(db_connection='DB_CONNECTION')
def __init__(self, db_connection):
self.db_connection = db_connection
def get_users(self):
self.db_connection.get('SELECT * FROM users')
Thank you again :)
Sorry, but your example is conceptually right, but engineeringly wrong. One should not inject a db connection but instead use a db pool of connections. So it means that one should use async
not to construct an application graph, but to acquire async resources.
I'll close the issue. If you want, you can always fork and modify the lib.
All in all, thanks for the idea.
Hi,
First of all, great job on this project. I've been testing pinject, injector and dependency-injector, and in my opinion your DI framework is more convenient and stable then the others. Most important, you support hashable objects as binding keys.
Are there any plans on implementing support for asyncio? It could be very useful to have an
asyncio
support.An example for having an async Provider Binding:
Thanks in advance :)