의존성 주입(그리고 부트스트래핑)
의존성 주입(dependency injection; DI) 을 위해 bootstrap.py 라는 새로운 컴포넌트를 추가한다.
아래는 부트스트랩이 없는 경우를 보여준다.
엔드포인트에서 수많은 초기화를 수행하고 주 의존성인 UoW를 여기저기 전달해야 한다.
아래는 부트스트래퍼가 이러한 책임을 맡은 모습을 보여준다.
(src/allocation/bootstrap.py)
import inspect
from typing import Callable
from allocation.adapters import orm, redis_eventpublisher
from allocation.adapters.notifications import (
AbstractNotifications,
EmailNotifications,
)
from allocation.service_layer import handlers, messagebus, unit_of_work
def bootstrap(
start_orm: bool = True,
uow: unit_of_work.AbstractUnitOfWork = unit_of_work.SqlAlchemyUnitOfWork(),
notifications: AbstractNotifications = None,
publish: Callable = redis_eventpublisher.publish,
) -> messagebus.MessageBus:
if notifications is None:
notifications = EmailNotifications()
if start_orm:
orm.start_mappers()
dependencies = {"uow": uow, "notifications": notifications, "publish": publish}
injected_event_handlers = {
event_type: [
inject_dependencies(handler, dependencies)
for handler in event_handlers
]
for event_type, event_handlers in handlers.EVENT_HANDLERS.items()
}
injected_command_handlers = {
command_type: inject_dependencies(handler, dependencies)
for command_type, handler in handlers.COMMAND_HANDLERS.items()
}
return messagebus.MessageBus(
uow=uow,
event_handlers=injected_event_handlers,
command_handlers=injected_command_handlers,
)
def inject_dependencies(handler, dependencies):
params = inspect.signature(handler).parameters
deps = {
name: dependency
for name, dependency in dependencies.items()
if name in params
}
return lambda message: handler(message, **deps)
(src/allocation/endpoints/flask_app.py)
app = Flask(__name__)
bus = bootstrap.bootstrap()
@app.route("/add_batch", methods=["POST"])
def add_batch():
eta = request.json["eta"]
if eta is not None:
eta = datetime.fromisoformat(eta).date()
cmd = commands.CreateBatch(
request.json["ref"], request.json["sku"], request.json["qty"], eta
)
bus.handle(cmd)
return "OK", 201
'python' 카테고리의 다른 글
파이썬 클린 코드 - 2장 (Pythonic code) (0) | 2022.01.27 |
---|---|
파이썬 클린 코드 - 1장 (코드 포매팅과 도구) (0) | 2022.01.25 |
Architecture Patterns with Python(12장) (0) | 2022.01.14 |
Architecture Patterns with Python(11장) (0) | 2022.01.07 |
Architecture Patterns with Python(10장) (0) | 2021.12.17 |