diff --git a/src/cpl-core/cpl/core/log/wrapped_logger.py b/src/cpl-core/cpl/core/log/wrapped_logger.py index a0bb5eb0..38411ed5 100644 --- a/src/cpl-core/cpl/core/log/wrapped_logger.py +++ b/src/cpl-core/cpl/core/log/wrapped_logger.py @@ -1,7 +1,8 @@ import inspect +from typing import Type from cpl.core.log import LoggerABC, LogLevel -from cpl.core.typing import Messages, Source +from cpl.core.typing import Messages from cpl.dependency.service_provider_abc import ServiceProviderABC @@ -11,18 +12,20 @@ class WrappedLogger(LoggerABC): LoggerABC.__init__(self) assert file_prefix is not None and file_prefix != "", "file_prefix must be a non-empty string" - t_logger = ServiceProviderABC.get_global_service(LoggerABC) - self._t_logger = type(t_logger) if t_logger is not None else None self._source = None self._file_prefix = file_prefix self._set_logger() - def _set_logger(self): - if self._t_logger is None: + @ServiceProviderABC.inject + def _set_logger(self, services: ServiceProviderABC): + from cpl.core.log import Logger + + t_logger: Type[Logger] = services.get_service_type(LoggerABC) + if t_logger is None: raise Exception("No LoggerABC service registered in ServiceProviderABC") - self._logger = self._t_logger(self._source, self._file_prefix) + self._logger = t_logger(self._source, self._file_prefix) def set_level(self, level: LogLevel): self._logger.set_level(level) diff --git a/src/cpl-dependency/cpl/dependency/service_provider.py b/src/cpl-dependency/cpl/dependency/service_provider.py index 02f455b8..3dcac39d 100644 --- a/src/cpl-dependency/cpl/dependency/service_provider.py +++ b/src/cpl-dependency/cpl/dependency/service_provider.py @@ -1,7 +1,7 @@ import copy import typing from inspect import signature, Parameter, Signature -from typing import Optional +from typing import Optional, Type from cpl.core.configuration import Configuration from cpl.core.configuration.configuration_model_abc import ConfigurationModelABC @@ -158,6 +158,13 @@ class ServiceProvider(ServiceProviderABC): return implementation + + def get_service_type(self, service_type: Type[T]) -> Optional[Type[T]]: + for descriptor in self._service_descriptors: + if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type): + return descriptor.service_type + return None + def get_services(self, service_type: T, *args, **kwargs) -> list[Optional[R]]: implementations = [] @@ -167,3 +174,10 @@ class ServiceProvider(ServiceProviderABC): implementations.extend(self._get_services(service_type)) return implementations + + def get_service_types(self, service_type: Type[T]) -> list[Type[T]]: + types = [] + for descriptor in self._service_descriptors: + if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type): + types.append(descriptor.service_type) + return types diff --git a/src/cpl-dependency/cpl/dependency/service_provider_abc.py b/src/cpl-dependency/cpl/dependency/service_provider_abc.py index ca0aa242..93ba3c8a 100644 --- a/src/cpl-dependency/cpl/dependency/service_provider_abc.py +++ b/src/cpl-dependency/cpl/dependency/service_provider_abc.py @@ -85,6 +85,20 @@ class ServiceProviderABC(ABC): Object of type Optional[:class:`cpl.core.type.T`] """ + @abstractmethod + def get_service_type(self,instance_type: Type[T]) -> Optional[Type[T]]: + r"""Returns the registered service type for loggers + + Parameter + --------- + instance_type: :class:`cpl.core.type.T` + The type of the searched instance + + Returns + ------- + Object of type Optional[:class:`type`] + """ + @abstractmethod def get_services(self, service_type: Type[T], *args, **kwargs) -> list[Optional[T]]: r"""Returns instance of given type @@ -99,6 +113,20 @@ class ServiceProviderABC(ABC): Object of type list[Optional[:class:`cpl.core.type.T`] """ + @abstractmethod + def get_service_types(self, service_type: Type[T]) -> list[Type[T]]: + r"""Returns all registered service types + + Parameter + --------- + service_type: :class:`cpl.core.type.T` + The type of the searched instance + + Returns + ------- + Object of type list[:class:`type`] + """ + @classmethod def inject(cls, f=None): r"""Decorator to allow injection into static and class methods