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
How to handle circular dependency [non-string keys for Dict provider] #327
Comments
Hi @ijalalfrz , I think that it is a typical circular dependency problem. In your case it seems like the loop is: The quick solution is to move File from .commands import Command, SaveRating, DoSomethingElse
class MessageBus:
COMMAND_HANDLERS = {}
def __init__(self):
from .handler import CommandHandler
command_handler = CommandHandler()
self.COMMAND_HANDLERS = {
SaveRating: command_handler.save_rating,
DoSomethingElse: command_handler.something_else,
}
def handle(self, command: Command):
self.COMMAND_HANDLERS[command]() File from dependency_injector import containers, providers
from . import repositories, messagebus
class Container(containers.DeclarativeContainer):
rating_repository = providers.Singleton(repositories.RatingRepository)
message_bus = providers.Factory(messagebus.MessageBus) And a sample code to run it: from .containers import Container
from .commands import SaveRating, DoSomethingElse
if __name__ == '__main__':
container = Container()
message_bus = container.message_bus()
message_bus.handle(SaveRating)
message_bus.handle(DoSomethingElse) The other wayThe other way is to pull File from .repositories import RatingRepository
class CommandHandler:
def __init__(self, rating_repo: RatingRepository):
self.rating_repo = rating_repo
def save_rating(self):
print('Saving rating')
def something_else(self):
print('Doing something else') File from typing import Dict, Callable, Any
from .commands import Command
class MessageBus:
def __init__(self, command_handlers: Dict[str, Callable[..., Any]]):
self.command_handlers = command_handlers
def handle(self, command: Command):
self.command_handlers[command]() File from dependency_injector import containers, providers
from . import repositories, handler, messagebus, commands
class Container(containers.DeclarativeContainer):
rating_repository = providers.Singleton(repositories.RatingRepository)
command_handler = providers.Singleton(
handler.CommandHandler,
rating_repo=rating_repository,
)
message_bus = providers.Factory(
messagebus.MessageBus,
command_handlers=providers.Dict({
commands.SaveRating: command_handler.provided.save_rating,
commands.DoSomethingElse: command_handler.provided.something_else,
}),
) Sample code for running is the same. Note: this option can not be implemented cause |
I have released version I've also included this example in the mini application examples: https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/commands-and-handlers |
Wow thank you @rmk135 for your fast reply and solution, i'm glad to contribute for this feature in this project |
Thank you for bringing up the issue @ijalalfrz . Appreciate you contribution. Let me know if you face other issues or need any other help. |
so i have handler class to be injected by container to get repositry object
service/handler.py
this handler is included in messagebus module like this
service/messagebus.py
but i also add MessageBus class on container that make me include
service/messagebus.py
tocontainer.py
container.py
when i run the app, it shows ImportError on
container.py
because i importedmessagebus
and inside it there is a handler object that importcontainer.py
what should i do to solve this? because message bus will be injected to other module in future
The text was updated successfully, but these errors were encountered: