Il ne semble pas y avoir de demande, mais il m'est arrivé de découvrir comment DI avec Python, alors ...
Inject semble avoir cessé de se développer en 2015. di-py ne semble pas très bien documenté. J'ai évité siringa parce que c'était une façon un peu perverse d'injecter des indices de type.
J'ai essayé l'injecteur avec la méthode d'élimination.
Comme expliqué dans la documentation, il s'agit d'un framework semblable à Google Guice. L'explication de Google Guice était facile à comprendre dans cet article. Notes d'utilisation de Google Guice
Les termes tels que Injecter, Module et Provider sont presque les mêmes que Google Guice, il peut donc être plus facile de comprendre Guice en premier. (Bien qu'il y ait encore des indices de type, faire de la DI dans un langage de script était difficile à comprendre)
todo_usecase.py
@singleton
class TodoUseCase:
def register(self, todo: Todo) - > None:
print("call todo_usecase.register")
todo_controller.py
@singleton
class TodoController:
@inject
def __init__(self, todo_usecase: TodoUseCase) -> None:
self.todo_usecase = todo_usecase
def create_todo(self, todo: Todo) -> None:
self.todo_usecase.register(todo)
if __name__=='__main__':
injector = Injector()
todo_controller: TodoController = injector.get(TodoController)
todo: Todo = Todo()
todo_controller.create_todo(todo)
Si vous voulez DI une instance normale, juste @ Inject
fera la DI pour vous.
Par défaut, il semble être singleton en ajoutant @ singleton
au lieu de singleton. (Guice n'est pas non plus singleton par défaut)
todo_repository.py
class TodoRepository:
@abstractmethod
def register(self, todo: Todo) -> None:
raise NotImplementedError
todo_datasource.py
class TodoDataSource(TodoRepository):
def register(self, todo: Todo) -> None:
print("call todo_datasource.register")
todo_usecase.py
@singleton
class TodoUseCase:
@inject
def __init__(self, todo_repository: TodoRepository) -> None:
self.todo_repository = todo_repository
def register(self, todo: Todo) -> None:
self.todo_repository.register(todo=todo)
class TodoDIModule(Module):
def configure(self, binder):
binder.bind(TodoRepository, to=TodoDataSource, scope=singleton)
if __name__=='__main__':
injector = Injector([TodoDIModule()])
todo_use_case: TodoUseCase = injector.get(TodoUseCase)
todo: Todo = Todo()
todo_use_case.register(todo)
Le but est de définir DI dans la classe d'implémentation Module. Il semble que la méthode pour le rendre singleton puisse également être effectuée en spécifiant la portée avec Module.
c'est tout.
Recommended Posts