64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
import importlib
|
|
import re
|
|
from functools import lru_cache
|
|
from typing import Type, TypeVar, Optional
|
|
from actions.config.config import Config
|
|
from actions.env.env_config_loader import EnvConfigLoader
|
|
|
|
# Genérico para garantir que o retorno respeite o Protocolo
|
|
T = TypeVar("T")
|
|
|
|
|
|
class ServiceFactory:
|
|
|
|
def __init__(self, package: str, table: str):
|
|
|
|
# Instancia o loader com o prefixo correto
|
|
env = EnvConfigLoader(".env")
|
|
|
|
# Ex: "packages.v1"
|
|
self.base_root = "packages.v1"
|
|
self.package = package
|
|
self.table = table
|
|
|
|
# Carrega config apenas uma vez
|
|
self.app_config = Config.get("app.json")
|
|
|
|
# Define a UF da aplicação
|
|
self.current_state = env.ORIUS_CLIENT_STATE
|
|
|
|
@lru_cache(maxsize=32)
|
|
def make(self, class_name: str, interface: Type[T]) -> T:
|
|
"""
|
|
Instancia um serviço dinamicamente com comportamento de Autoload.
|
|
"""
|
|
# 1. Converte CamelCase para snake_case (Autoload style)
|
|
# Ex: TAtoIndexService -> t_ato_index_service
|
|
module_name = re.sub(r"(?<!^)(?=[A-Z])", "_", class_name).lower()
|
|
|
|
# 2. Monta o caminho completo
|
|
# Ex: packages.v1.servicos.balcao.services.t_ato.SP.t_ato_index_service
|
|
import_path = (
|
|
f"{self.base_root}.{self.package}.services."
|
|
f"{self.table}.{self.current_state}.{module_name}"
|
|
)
|
|
|
|
try:
|
|
# 3. Importação Dinâmica
|
|
module = importlib.import_module(import_path)
|
|
|
|
# 4. Pega a classe do módulo
|
|
clazz = getattr(module, class_name)
|
|
|
|
# 5. Retorna a INSTÂNCIA da classe (já com () )
|
|
# Se seus serviços precisam de argumentos no __init__, altere aqui.
|
|
return clazz()
|
|
|
|
except ImportError as e:
|
|
raise ImportError(
|
|
f"FATAL: Não foi possível carregar o serviço '{class_name}' para o estado '{self.current_state}'.\nCaminho tentado: {import_path}\nErro: {e}"
|
|
)
|
|
except AttributeError:
|
|
raise AttributeError(
|
|
f"FATAL: O arquivo '{module_name}.py' existe, mas a classe '{class_name}' não foi encontrada dentro dele."
|
|
)
|