Source code for wired.dataclasses.decorators

from venusian import Scanner, attach

from wired import ServiceRegistry

from .registration import register_dataclass


# noinspection PyPep8Naming
[docs] class singleton: """ Register an instance of a dataclass as a singleton. The singleton will be registered with a :class:`wired.ServiceRegistry` when performing a venusian scan. .. code-block:: python @singleton @dataclass class Settings: punctuation: str = '' .. seealso:: :meth:`wired.ServiceRegistry.register_singleton` """ def __init__(self, for_=None, context=None, name: str = ''): self.for_ = for_ self.context = context if context else for_ self.name = name def __call__(self, wrapped): def callback(scanner: Scanner, name: str, cls): registry: ServiceRegistry = getattr(scanner, 'registry') # Later we can do some dataclass field sniffing on singletons instance = cls() # If there is a for_ use it, otherwise, register for the same # class as the instance for_ = self.for_ if self.for_ else cls registry.register_singleton( instance, for_, context=self.context, name=self.name ) attach(wrapped, callback, category='wired') return wrapped
# noinspection PyPep8Naming
[docs] class factory: """ Register a factory for a dataclass that can sniff dependencies. The factory will be registered with a :class:`wired.ServiceRegistry` when performing a venusian scan. .. code-block:: python from sqlalchemy.orm import Session @factory @dataclass class LoginService: db: Session # ... later registry = ServiceRegistry() scanner = venusian.Scanner(registry=registry) scanner.scan() # ... later container = registry.create_container() svc = container.get(LoginService) .. seealso:: - :func:`wired.dataclasses.register_dataclass` - :func:`wired.ServiceRegistry.register_factory` """ def __init__(self, for_=None, context=None, name: str = ''): self.for_ = for_ self.context = context self.name = name def __call__(self, wrapped): def callback(scanner: Scanner, name: str, cls): registry: ServiceRegistry = getattr(scanner, 'registry') # If there is a for_ use it, otherwise, register for the same # class as the instance for_ = self.for_ if self.for_ else cls register_dataclass( registry, cls, for_=for_, context=self.context, name=self.name ) attach(wrapped, callback, category='wired') return wrapped