[Feature Request] Get a registered dependency outside of route handlers as well
Is your feature request related to a problem? Please describe your use case. I am trying to access a service that I have registered as a dependency in an event handler to a custom signal.
class MyService:
def __init__(self, connection: DBConnection):
self._connection = connection
@app.signal("some.dummy.event")
def dummy_event_handler(**context):
app = Sanic.get_app("my-app")
request = Request.get_current()
dependency_callable = app.ext._injection_registry.get(dependency_type)
# I'm not sure what the impact of using this request object is.
# What if I'm calling this after the request that dispatched this event
# has already been processed and the response was sent?
service = await dependency_callable(request)
...
Describe the solution you'd like It would be nice to get an API which takes in a type and attempts to get the dependency from the registry.
class MyService:
...
@app.signal("some.dummy.event")
def dummy_event_handler(**context):
service = Sanic.get_app("my-app").ext.get_dependency(MyService)
# do something with the service
Certainly! Here's an example of an API that takes a type and attempts to retrieve the corresponding dependency from the registry:
class DependencyRegistry:
def __init__(self):
self._registry = {}
def register_dependency(self, dependency_type, dependency):
self._registry[dependency_type] = dependency
def get_dependency(self, dependency_type):
return self._registry.get(dependency_type)
class MyService:
def __init__(self, connection: DBConnection):
self._connection = connection
app = Sanic("my-app")
registry = DependencyRegistry()
@app.route("/dependency/<dependency_type>")
async def get_dependency(request, dependency_type):
dependency = registry.get_dependency(dependency_type)
if dependency is None:
return json({"error": "Dependency not found"}, status=404)
return json({"dependency": str(dependency)})
@app.listener("before_server_start")
async def setup_registry(app, loop):
# Register dependencies in the registry
registry.register_dependency(DBConnection, "database_connection")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
In this example, we have a DependencyRegistry class that maintains a dictionary _registry for storing dependencies. It provides methods to register and retrieve dependencies.
The MyService class is just a placeholder representing a class that requires dependencies.
The Sanic app (app) is created with the name "my-app". We define a route /dependency/<dependency_type> that accepts a dependency_type parameter. When a GET request is made to this route, the API attempts to retrieve the corresponding dependency from the registry based on the provided dependency_type. If the dependency is found, it is returned in the response. Otherwise, a 404 error response is returned.
In the before_server_start listener, we can register dependencies in the registry. In this example, we register a DBConnection dependency with the value "database_connection".
You can modify and expand this example to suit your specific needs.
I'm sorry @BDadmehr0 , but I don't think your proposed solution is what I'm looking for. When I said API, I wasn't talking about an HTTP endpoint but in the more general sense. Also your DependencyRegistry doesn't handle resolving the dependencies required by the dependency I'm trying to get.
Sorry, but I can't think of any other solution