https://python-dependency-injector.ets-labs.org

  • 0) Introduction
    • Dependency injection framework for Python.
    • 용접같은 Coupling 은 낮아지고, 나사같은 Cohesion(응집력) 은 높아지고...
    • ...
  • 1) Examples
    • Application example (single container)
      • "dependency_injector.containers.DeclarativeContainer" 작성.
      • logger 및 config 셋팅.
      • db 및 aws boto3 등에 리소스별 "dependency_injector.providers.Singleton" 셋팅.
      • 각 서비스별 "dependency_injector.providers.Factory" 셋팅.
      • ...
    • Application example (multiple containers) : ㅎㅎ;;;
    • Decoupled packages example (multiple containers) : ㅎㅎ;;;
    • Boto3 example
      • ...
    • FastAPI example
      • ...
  • 2) Tutorials
  • 3) Providers : Object 를 만들고, DI 를 하도록 호출 할 수 있음...
    • Factory provider
      • 정의한 클래스를 기반으로~ 매번 new object 를 생성 함.
      • Factory 상속&재정의, AbstractFactory, FactoryAggregate 등등등 참고.
    • Singleton provider
      • 첫 object 생성 후, 동일한 단일 개체를 반환 함.
      • DI 방식은 Factory 와 똑같다고 보면 됨.
      • 단일개체 scope는 container 에 엮여있고, 서로다른 container 에서 호출하면~ 두 싱글톤이 다름!
      • 기본적으로, 'thread-safe' 하지않음... 'multi-threading' 환경에서는 동기화를 위한 고민을 해야함.
      • (ThreadSafeSingleton, ThreadLocalSingleton, ...)
    • Callable provider
      • 호출 할 수 있는 "함수 등등"을 기반으로~ Factory 와 같은 동작을 제공 함.
      • 예) pw_hash_util = providers.Callable(passlib.hash.sha256_crypt.hash, sha256_crypt 관련 인자...)
      • 예) pw_verify_util = providers.Callable(passlib.hash.sha256_crypt.verify)
    • Coroutine provider
      • 비동기 호출 할 수 있는 "코루틴 함수"를 기반으로~ Factory 와 같은 동작을 제공 함.
      • ...
    • Object, List, Dict provider
      • 각 타입의 형태로 제공을 함.
      • ...
    • Configuration provider
      • 다양한식의 설정 정보들을 '타 provider' 가 사용 할 수 있도록 제공 함. (as_int, as_float, as_ 등등 지원함)
      • 예) config = providers.Configuration() // "config.맴버" 으로 다양한 설정 정보들을 접근하여 사용.
        • providers.Configuration(ini_files=["./config.ini"])
        • providers.Configuration(yaml_files=["./config.yaml"])
        • providers.Configuration(json_files=["./config.json"])
        • providers.Configuration(pydantic_settings=[Settings()])
        • config.from_dict( {...} )
        • config.my_key.from_env("MY_KEY", as_=str, required=False, default='...')
        • config.the_day.from_value(date(2022, 3, 13))
    • Resource provider
      • "init 및 shutdow" 를 기반으로~ 컴포넌트를 제공 함.
      • 싱글톤과 비슷하게 됨. (한번의 초기화 후~ 타 prodiver 에서 사용 하는식...)
      • container 에서 한번에 모든 리소스를 init_resources() 및 shutdown_resources() 할 수 있음.
      • 지원하는 initializer 타입
        • Function
          • 함수를 정의하여, 초기화 및 리소스 리턴을 하던지...
          • logging 같은 글로벌 리소스는 함수로 (리턴없이) 설정만 한다던지... 하는식으로 사용!
          • 해당 리소스의 shutdow 커스텀은 지원 안됨.
        • Generator
          • 함수를 두단계(initialization -> shutdown) 으로 정의, yield 으로 리소스 리턴
          • (마찬가지로, 리턴없이 yield 만 써도 됨)
        • Subclass of resources.Resource
          • dependency_injector.resources.Resource 를 상속받아서 클래스 정의
          • init() 및 shutdown() 를 구현하여 활용 되도록 하면 됨.
        • 비동기 프레임워크를 사용할때는~ 비동기식으로 정의 해야 될 수 있음!
          • 예) async def init_f(...):
            • return await 리소스()
          • 예) async def init_g(...):
            • r = await 리소스() ~> yield r ~> await r.close()
          • (container 에서도 await 으로 init_resources() 및 shutdown_resources() 으로 호출 해야함)
    • ...
  • 4) Containers : provider들을 모아서 관리하는 곳 
    • Declarative container
      • 해당 써브클래스를 통해서, provider들의 구성을 정의해두고~ 해당 contianer instance 를 만들어 사용.
      • ...
    • Dynamic container
      • 런타임시 상황에 맞게 contianer instance 에 필요한 provider들을 구성하여 사용.
      • (구조적으로... 어플리케이션이 실행된 이후~ 필요한 dependency 에 접근이 가능한 상황일때 유용)
      • ...
    • ...
    • Reset container singletons : ...
    • Check container dependencies : ...
    • Container providers traversal
      • for provider in container.traverse(types=[providers.Resource]): 식으로 관련 provider 들을 탐색할수있음.
  • 5) Wiring : container 의 provider 를 주입(Inject) 하는것
    • Decorator @inject
      • DI 를 하고싶은 함수 등등에, @inject 를 데코하면 됨. (가급적이면 첫 데코로 해야 잘 돌아감)
    • Markers
      • DI 를 하고싶은 함수 등등의 인자에, 마커(Marker)를 사용하여 기본값으로 지정하면 됨.
      • container 그자체 혹은... container 의 provider 혹은... container의 각종 설정값 으로 지정 할 수 있음.
    • String identifiers : container 호출 없이~ 문자로 써줄수도 있지만...
    • Making injections into modules and class attributes : 모듈로써 or  클래스 속성으로써 마킹을 할수도있음!
    • Wiring with modules and packages
      • 사용할 모듈을 container.wire() 으로 알려 주어야 함.
      • 이렇게 '와이어링' 을 다 해두면, 실제 마커(Marker)가 있는 함수 등등이 호출 될 때~ DI 가 되도록 패치 됨.
      • 기존 DI 를 언패치 하려면, container.unwire() 를 호출하면 됨.
      • (코드베이스 가 크면... 와이어링 시간이 오래 걸릴수 있음... rewiring 하지 않도록 주의)
      • (와이어링 이후 모듈 단위로 가져다 쓰는것을 권장)
    • Wiring configuration
      • container 내부에 "WiringConfiguration" 를 명시하여, container 인스턴스 생성시~ 자동으로 wire() 호출하도록 가능.
    • Asynchronous injections
      • async 함수 호출을 통해서도 '와이어링' 을 할 수있도록 지원함! (FastAPI 용?)
      • async resource provider 에 Closing 마커(Marker) 사용가능.
      • ...
    • Wiring of dynamically imported modules : ...
    • Integration with other frameworks : ...
  • 6) Other examples
    • Use cases example : ...
    • Password hashing example : ...
    • ...

-끝-

'랭귀지&프레임웤' 카테고리의 다른 글

파이썬 프로그래밍  (0) 2023.01.29
python ruff & uv  (0) 2022.10.26
FastAPI 심화  (0) 2022.09.04
FastAPI  (0) 2022.06.15
"certificate verify failed: unable to get local issuer certificate"  (0) 2021.05.30

+ Recent posts