ReflectionInstance
ReflectionInstance inspecciona un objeto ya construido: sus datos actuales, la clase que lo define, métodos, propiedades y firmas. Es útil para herramientas de diagnóstico, adaptadores y extensiones que necesitan examinar un servicio sin crear otra instancia. No ejecuta los métodos descubiertos ni resuelve sus dependencias.
Inicio rápido
Sección titulada «Inicio rápido»Para examinar datos de una clase importada basta con construir el wrapper alrededor del objeto.
from orionis.introspection import ReflectionInstancefrom orionis.support.types import StdClass
record = StdClass(status="ready")record_reflection = ReflectionInstance(record)assert record_reflection.getPublicAttributes() == {"status": "ready"}assert record_reflection.getInstance() is recordPreparar un objeto importable
Sección titulada «Preparar un objeto importable»Guarda esta clase de ejemplo en app/services/report_service.py. Las secciones siguientes reutilizan service y reflected. La variedad de miembros permite comprobar cada filtro; en una aplicación normal basta con los miembros que necesites.
class ReportBase: def inherited(self) -> str: return "base"
@property def inherited_label(self) -> str: return "base label"
class ReportService(ReportBase): """Generate reports for an application."""
title: str _token: str __secret: str
def __init__(self, title: str = "Sales") -> None: self.title = title self._token = "internal" self.__secret = "private" self.__trace__ = "trace"
def render(self, limit: int = 10) -> str: """Render the report.""" return f"{self.title}: {limit}"
async def refresh(self) -> str: return self.title
def _prepare(self) -> str: return self._token
async def _prepare_async(self) -> str: return self._token
def __sign(self) -> str: return self.__secret
async def __sign_async(self) -> str: return self.__secret
@classmethod def category(cls) -> str: return cls.__name__
@classmethod async def category_async(cls) -> str: return cls.__name__
@classmethod def _category(cls) -> str: return cls.__name__
@classmethod async def _category_async(cls) -> str: return cls.__name__
@classmethod def __category(cls) -> str: return cls.__name__
@classmethod async def __category_async(cls) -> str: return cls.__name__
@staticmethod def valid() -> bool: return True
@staticmethod async def valid_async() -> bool: return True
@staticmethod def _valid() -> bool: return True
@staticmethod async def _valid_async() -> bool: return True
@staticmethod def __valid() -> bool: return True
@staticmethod async def __valid_async() -> bool: return True
@property def label(self) -> str: """Human-readable report label.""" return self.title.upper()
@property def _length(self) -> int: return len(self.title)
@property def __label(self) -> str: return self.__secret
def temporary(self) -> None: return Nonefrom app.services.report_service import ReportServicefrom orionis.introspection import ReflectionInstance
service = ReportService()reflected = ReflectionInstance(service)assert reflected.getInstance() is service__init__
Sección titulada «__init__»def __init__(self, instance: Any) -> None: ...instance es obligatorio y debe ser un objeto, no una clase. Rechaza clases y objetos cuyo instance.__class__.__module__ sea builtins o abc con TypeError; rechaza el módulo __main__ con ValueError. No comprueba que el módulo indicado sea importable: una clase sintética con otro nombre de módulo también puede aceptarse. El ejemplo utiliza una clase definida en un archivo importable para poder recuperar su código fuente y evitar __main__. La construcción no realiza todavía los recorridos de atributos o métodos.
reflected = ReflectionInstance(service)Identidad y metadatos
Sección titulada «Identidad y metadatos»Estos métodos no requieren argumentos. Devuelven referencias o metadatos de la clase del objeto, no una copia del servicio.
getClassName(), getModuleName() y getModuleWithClassName() utilizan los nombres capturados al construir el wrapper. Si después cambias __name__ o __module__ de la clase, clearCache() no actualiza esos campos; construye otro wrapper para obtener los nuevos nombres.
getInstance
Sección titulada «getInstance»def getInstance(self) -> Any: ...Devuelve el mismo objeto reflejado (Any).
assert reflected.getInstance() is servicegetClass
Sección titulada «getClass»def getClass(self) -> type: ...Devuelve su clase (type).
assert reflected.getClass() is ReportServicegetClassName
Sección titulada «getClassName»def getClassName(self) -> str: ...Devuelve __name__ de la clase como str.
assert reflected.getClassName() == "ReportService"getModuleName
Sección titulada «getModuleName»def getModuleName(self) -> str: ...Devuelve el módulo de la clase como str.
assert reflected.getModuleName() == "app.services.report_service"getModuleWithClassName
Sección titulada «getModuleWithClassName»def getModuleWithClassName(self) -> str: ...Concatena módulo y nombre simple de clase. No usa __qualname__ para clases anidadas.
assert reflected.getModuleWithClassName() == "app.services.report_service.ReportService"getDocstring
Sección titulada «getDocstring»def getDocstring(self) -> str | None: ...Devuelve el __doc__ de la clase, o None; no el docstring de __init__.
assert reflected.getDocstring() == "Generate reports for an application."getBaseClasses
Sección titulada «getBaseClasses»def getBaseClasses(self) -> tuple[type, ...]: ...Devuelve una tupla con las bases directas, no toda la jerarquía MRO.
assert reflected.getBaseClasses()[0].__name__ == "ReportBase"getAnnotations
Sección titulada «getAnnotations»def getAnnotations(self) -> dict[str, type]: ...Devuelve un diccionario de anotaciones de la clase. Los nombres privados propios se presentan sin el prefijo de mangling. No infiere tipos a partir de los valores ni convierte anotaciones en dependencias resueltas.
assert "title" in reflected.getAnnotations()assert "__secret" in reflected.getAnnotations()getFile
Sección titulada «getFile»def getFile(self) -> str | None: ...Devuelve la ruta del archivo de la clase (str), memoizada, o None cuando inspect genera TypeError u OSError.
assert reflected.getFile().endswith("report_service.py")getSourceCode
Sección titulada «getSourceCode»def getSourceCode(self, method: str | None=None) -> str | None: ...Sin method o con un valor vacío devuelve el código de la clase. Con un nombre devuelve el código de un método clasificado en getMethods(), admitiendo nombres privados como __sign. Los dunder, incluido __init__, no pertenecen a esa lista y su consulta individual devuelve None. También devuelve None para un método ausente o si la fuente no se puede recuperar (TypeError/OSError). Cada variante se memoiza.
assert "class ReportService" in reflected.getSourceCode()assert "def render" in reflected.getSourceCode("render")assert "def __sign" in reflected.getSourceCode("__sign")assert reflected.getSourceCode("__init__") is Noneassert reflected.getSourceCode("missing") is NoneAtributos del objeto
Sección titulada «Atributos del objeto»El recorrido usa vars(instance): solo enumera entradas del __dict__ de la instancia, sin incluir automáticamente variables de clase ni valores calculados de propiedades. Un objeto con __slots__ y sin __dict__ puede construirse, pero estos recorridos fallan con TypeError.
Los diccionarios se almacenan y devuelven por referencia. Los prefijos son una clasificación de nombres de Python, no un control de acceso. Un privado propio como _ReportService__secret aparece como __secret; un privado heredado con otro prefijo puede clasificarse como protegido.
getAttributes
Sección titulada «getAttributes»def getAttributes(self) -> dict[str, Any]: ...Combina públicos, protegidos, privados propios y dunder en dict[str, Any].
assert reflected.getAttributes()["__secret"] == "private"getPublicAttributes
Sección titulada «getPublicAttributes»def getPublicAttributes(self) -> dict[str, Any]: ...Devuelve entradas que no empiezan con _.
assert reflected.getPublicAttributes() == {"title": "Sales"}getProtectedAttributes
Sección titulada «getProtectedAttributes»def getProtectedAttributes(self) -> dict[str, Any]: ...Devuelve entradas con _ que no fueron clasificadas como privadas propias o dunder.
assert reflected.getProtectedAttributes()["_token"] == "internal"getPrivateAttributes
Sección titulada «getPrivateAttributes»def getPrivateAttributes(self) -> dict[str, Any]: ...Devuelve privados propios con nombres desmangleados.
assert reflected.getPrivateAttributes()["__secret"] == "private"getDunderAttributes
Sección titulada «getDunderAttributes»def getDunderAttributes(self) -> dict[str, Any]: ...Devuelve nombres que empiezan y terminan con __.
assert reflected.getDunderAttributes()["__trace__"] == "trace"getMagicAttributes
Sección titulada «getMagicAttributes»def getMagicAttributes(self) -> dict[str, Any]: ...Alias de getDunderAttributes(); devuelve el mismo diccionario cacheado.
assert reflected.getMagicAttributes() is reflected.getDunderAttributes()hasAttribute
Sección titulada «hasAttribute»def hasAttribute(self, name: str) -> bool: ...name: str es obligatorio. Comprueba el diccionario combinado o hasattr(instance, name) y devuelve bool; por ello también puede detectar variables de clase y propiedades. El recorrido del diccionario se ejecuta primero.
assert reflected.hasAttribute("title")assert reflected.hasAttribute("label")assert not reflected.hasAttribute("missing")getAttribute
Sección titulada «getAttribute»def getAttribute(self, name: str, default: Any=None) -> Any: ...name es obligatorio; default=None se usa si no existe. Prioriza el diccionario cacheado y hace también una consulta getattr; esta consulta puede ejecutar descriptores. Para privados propios usa el nombre desmangleado. Las excepciones de un getter pueden propagarse.
assert reflected.getAttribute("__secret") == "private"assert reflected.getAttribute("missing", "fallback") == "fallback"assert reflected.getAttribute("label") == "SALES"getAttributeDocstring
Sección titulada «getAttributeDocstring»def getAttributeDocstring(self, name: str) -> str | None: ...Obtiene el __doc__ del valor del atributo, o None; no extrae comentarios de la declaración. name es obligatorio y admite privados propios. Lanza AttributeError si no existe.
assert reflected.getAttributeDocstring("title") == str.__doc__setAttribute
Sección titulada «setAttribute»def setAttribute(self, name: str, value: Any) -> bool: ...name y value son obligatorios. Valida un identificador Python que no sea palabra reservada (AttributeError); rechaza valores callable (TypeError). Aplica mangling a privados propios, llama a setattr, vacía toda la caché y devuelve True. Las restricciones de setters o slots se conservan.
assert reflected.setAttribute("region", "EU") is Trueassert service.region == "EU"assert reflected.setAttribute("__secret", "updated") is Trueassert reflected.getAttribute("__secret") == "updated"removeAttribute
Sección titulada «removeAttribute»def removeAttribute(self, name: str) -> bool: ...name es obligatorio. Elimina el atributo con delattr, invalida la caché y devuelve True. Considera ausente cualquier valor obtenido igual a None, así que también rechaza atributos existentes cuyo valor sea None con AttributeError. Puede fallar para propiedades sin deleter o atributos solo de clase.
assert reflected.removeAttribute("region") is Trueassert not reflected.hasAttribute("region")Filtrar métodos
Sección titulada «Filtrar métodos»El escaneo recorre dir(type(instance)) con acceso estático a descriptores: incluye métodos heredados, distingue funciones de instancia, classmethod y staticmethod, y separa corrutinas mediante inspect.iscoroutinefunction. No invoca los métodos ni los getters de propiedades. Una función que devuelva un awaitable sin ser una función de corrutina sigue en el filtro sync.
Los privados propios se devuelven como __sign, sin el prefijo de clase. getMethods() excluye dunder y combina las categorías; no constituye un orden de ejecución. Los filtros no reciben argumentos y devuelven listas cacheadas de nombres, no métodos ligados.
getMethods
Sección titulada «getMethods»def getMethods(self) -> list[str]: ...Todos los métodos clasificados, sin dunder.
assert "render" in reflected.getMethods()assert "inherited" in reflected.getMethods()getDunderMethods
Sección titulada «getDunderMethods»def getDunderMethods(self) -> list[str]: ...Nombres dunder de la clase, incluidos heredados. El recorrido recoge cualquier nombre __...__ de dir(cls) antes de comprobar si es callable; por ello puede incluir entradas como __module__.
assert "__init__" in reflected.getDunderMethods()getMagicMethods
Sección titulada «getMagicMethods»def getMagicMethods(self) -> list[str]: ...Alias de getDunderMethods().
assert reflected.getMagicMethods() is reflected.getDunderMethods()Métodos de instancia
Sección titulada «Métodos de instancia»getPublicMethods(self) -> list[str] — Devuelve métodos públicos, tanto sync como async.
assert "render" in reflected.getPublicMethods()getPublicSyncMethods(self) -> list[str] — Devuelve métodos públicos síncronos.
assert "render" in reflected.getPublicSyncMethods()getPublicAsyncMethods(self) -> list[str] — Devuelve métodos públicos asíncronos.
assert "refresh" in reflected.getPublicAsyncMethods()getProtectedMethods(self) -> list[str] — Devuelve métodos protegidos, tanto sync como async.
assert "_prepare" in reflected.getProtectedMethods()getProtectedSyncMethods(self) -> list[str] — Devuelve métodos protegidos síncronos.
assert "_prepare" in reflected.getProtectedSyncMethods()getProtectedAsyncMethods(self) -> list[str] — Devuelve métodos protegidos asíncronos.
assert "_prepare_async" in reflected.getProtectedAsyncMethods()getPrivateMethods(self) -> list[str] — Devuelve métodos privados propios, tanto sync como async.
assert "__sign" in reflected.getPrivateMethods()getPrivateSyncMethods(self) -> list[str] — Devuelve métodos privados propios síncronos.
assert "__sign" in reflected.getPrivateSyncMethods()getPrivateAsyncMethods(self) -> list[str] — Devuelve métodos privados propios asíncronos.
assert "__sign_async" in reflected.getPrivateAsyncMethods()Métodos de clase
Sección titulada «Métodos de clase»getPublicClassMethods(self) -> list[str] — Devuelve métodos públicos, tanto sync como async.
assert "category" in reflected.getPublicClassMethods()getPublicClassSyncMethods(self) -> list[str] — Devuelve métodos públicos síncronos.
assert "category" in reflected.getPublicClassSyncMethods()getPublicClassAsyncMethods(self) -> list[str] — Devuelve métodos públicos asíncronos.
assert "category_async" in reflected.getPublicClassAsyncMethods()getProtectedClassMethods(self) -> list[str] — Devuelve métodos protegidos, tanto sync como async.
assert "_category" in reflected.getProtectedClassMethods()getProtectedClassSyncMethods(self) -> list[str] — Devuelve métodos protegidos síncronos.
assert "_category" in reflected.getProtectedClassSyncMethods()getProtectedClassAsyncMethods(self) -> list[str] — Devuelve métodos protegidos asíncronos.
assert "_category_async" in reflected.getProtectedClassAsyncMethods()getPrivateClassMethods(self) -> list[str] — Devuelve métodos privados propios, tanto sync como async.
assert "__category" in reflected.getPrivateClassMethods()getPrivateClassSyncMethods(self) -> list[str] — Devuelve métodos privados propios síncronos.
assert "__category" in reflected.getPrivateClassSyncMethods()getPrivateClassAsyncMethods(self) -> list[str] — Devuelve métodos privados propios asíncronos.
assert "__category_async" in reflected.getPrivateClassAsyncMethods()Métodos estáticos
Sección titulada «Métodos estáticos»getPublicStaticMethods(self) -> list[str] — Devuelve métodos públicos, tanto sync como async.
assert "valid" in reflected.getPublicStaticMethods()getPublicStaticSyncMethods(self) -> list[str] — Devuelve métodos públicos síncronos.
assert "valid" in reflected.getPublicStaticSyncMethods()getPublicStaticAsyncMethods(self) -> list[str] — Devuelve métodos públicos asíncronos.
assert "valid_async" in reflected.getPublicStaticAsyncMethods()getProtectedStaticMethods(self) -> list[str] — Devuelve métodos protegidos, tanto sync como async.
assert "_valid" in reflected.getProtectedStaticMethods()getProtectedStaticSyncMethods(self) -> list[str] — Devuelve métodos protegidos síncronos.
assert "_valid" in reflected.getProtectedStaticSyncMethods()getProtectedStaticAsyncMethods(self) -> list[str] — Devuelve métodos protegidos asíncronos.
assert "_valid_async" in reflected.getProtectedStaticAsyncMethods()getPrivateStaticMethods(self) -> list[str] — Devuelve métodos privados propios, tanto sync como async.
assert "__valid" in reflected.getPrivateStaticMethods()getPrivateStaticSyncMethods(self) -> list[str] — Devuelve métodos privados propios síncronos.
assert "__valid" in reflected.getPrivateStaticSyncMethods()getPrivateStaticAsyncMethods(self) -> list[str] — Devuelve métodos privados propios asíncronos.
assert "__valid_async" in reflected.getPrivateStaticAsyncMethods()Firmas y edición de métodos
Sección titulada «Firmas y edición de métodos»hasMethod
Sección titulada «hasMethod»def hasMethod(self, name: str) -> bool: ...Comprueba si name está en el conjunto de métodos clasificados de la clase. No consulta callables añadidos solamente al objeto ni incluye dunder.
assert reflected.hasMethod("render")assert reflected.hasMethod("__sign")assert not reflected.hasMethod("__init__")getMethodSignature
Sección titulada «getMethodSignature»def getMethodSignature(self, name: str) -> inspect.Signature: ...Con name obligatorio devuelve inspect.Signature del miembro callable de la clase, con mangling para privados propios. Admite dunder como __init__, sin depender de hasMethod(). Un método de instancia conserva self en esa firma; un classmethod ya ligado a la clase no conserva cls. Lanza AttributeError si no es callable; los errores de inspección se propagan.
assert list(reflected.getMethodSignature("render").parameters) == ["self", "limit"]assert list(reflected.getMethodSignature("__init__").parameters) == ["self", "title"]assert list(reflected.getMethodSignature("__sign").parameters) == ["self"]getMethodDocstring
Sección titulada «getMethodDocstring»def getMethodDocstring(self, name: str) -> str | None: ...Con name obligatorio devuelve el docstring del callable de la clase, o None. Admite privados propios y memoiza el resultado. Lanza AttributeError si el miembro no es callable o está ausente.
assert reflected.getMethodDocstring("render") == "Render the report."setMethod
Sección titulada «setMethod»def setMethod(self, name: str, method: Callable) -> bool: ...name y method: Callable son obligatorios. Valida el nombre como setAttribute, exige callable (TypeError), lo asigna al objeto y devuelve True, vaciando la caché. No lo liga automáticamente con self ni lo incorpora a los filtros de clase. Usa types.MethodType si la función requiere una instancia.
from types import MethodType
assert reflected.setMethod("extra", lambda: "ready") is Trueassert service.extra() == "ready"assert not reflected.hasMethod("extra")
def describe(instance): return instance.title
reflected.setMethod("describe", MethodType(describe, service))assert service.describe() == "Sales"removeMethod
Sección titulada «removeMethod»def removeMethod(self, name: str) -> None: ...Con name obligatorio primero exige que hasMethod() sea verdadero y luego elimina el miembro de la clase, no de la instancia. Devuelve None; afecta a todas las instancias de esa clase. Lanza AttributeError si falta. No elimina métodos solo heredados desde una subclase. Utilízalo para métodos propios públicos o protegidos: un método privado normal no puede eliminarse mediante esta API, porque la comprobación y la eliminación no aplican las mismas reglas de mangling. Tanto __secret como _Class__secret producen AttributeError para ese caso.
assert reflected.removeMethod("temporary") is Noneassert not hasattr(service, "temporary")constructorSignature
Sección titulada «constructorSignature»def constructorSignature(self) -> Signature: ...Sin argumentos devuelve un Signature de Orionis para __init__. Sus mapas resolved, unresolved y ordered contienen objetos Argument; no son servicios ya construidos. Se memoiza. Consulta la guía de dependencias para la clasificación completa.
dependencies = reflected.constructorSignature()assert list(dependencies.ordered) == ["title"]assert "title" in dependencies.resolvedmethodSignature
Sección titulada «methodSignature»def methodSignature(self, method_name: str) -> Signature: ...Con method_name obligatorio devuelve un Signature de Orionis para el método ligado al objeto y omite self. Comprueba hasMethod(), admite privados propios y memoiza por nombre. Lanza AttributeError para un método no clasificado. No llama al contenedor ni ejecuta el método.
dependencies = reflected.methodSignature("render")assert list(dependencies.ordered) == ["limit"]assert "limit" in dependencies.resolvedPropiedades
Sección titulada «Propiedades»La enumeración de property recorre solo ReportService.__dict__: no incluye propiedades heredadas ni nombres dunder __...__. Los getters no se ejecutan durante el recorrido. La consulta de una firma o docstring busca el descriptor con getattr sobre la clase y sí puede encontrar una propiedad heredada; getProperty() exige que aparezca en la lista propia.
getProperties
Sección titulada «getProperties»def getProperties(self) -> list[str]: ...Devuelve list[str] de propiedades propias de todas las visibilidades.
assert reflected.getProperties() == ["label", "_length", "__label"]assert "inherited_label" not in reflected.getProperties()getPublicProperties
Sección titulada «getPublicProperties»def getPublicProperties(self) -> list: ...Devuelve una lista de nombres públicos propios.
assert reflected.getPublicProperties() == ["label"]getProtectedProperties
Sección titulada «getProtectedProperties»def getProtectedProperties(self) -> list: ...Devuelve una lista de nombres protegidos propios.
assert reflected.getProtectedProperties() == ["_length"]getPrivateProperties
Sección titulada «getPrivateProperties»def getPrivateProperties(self) -> list: ...Devuelve una lista de privados propios desmangleados.
assert reflected.getPrivateProperties() == ["__label"]getProperty
Sección titulada «getProperty»def getProperty(self, name: str) -> Any: ...name es obligatorio. Ejecuta el getter y devuelve su valor (Any). Admite privados propios; lanza AttributeError para una propiedad fuera de la lista. Las excepciones del getter se propagan.
assert reflected.getProperty("label") == "SALES"assert reflected.getProperty("__label") == "updated"getPropertySignature
Sección titulada «getPropertySignature»def getPropertySignature(self, name: str) -> inspect.Signature: ...name es obligatorio. Devuelve el inspect.Signature del getter fget, incluyendo self, sin ejecutarlo. Se memoiza; admite privados propios y lanza AttributeError si el miembro no es property. Un descriptor sin getter no puede inspeccionarse normalmente.
assert list(reflected.getPropertySignature("label").parameters) == ["self"]getPropertyDocstring
Sección titulada «getPropertyDocstring»def getPropertyDocstring(self, name: str) -> str: ...name es obligatorio. Devuelve el docstring del getter como str, o "" si no hay docstring. Se memoiza y admite privados propios. Lanza AttributeError si no es una propiedad.
assert reflected.getPropertyDocstring("label") == "Human-readable report label."assert reflected.getPropertyDocstring("_length") == ""Caché local y protocolo de diccionario
Sección titulada «Caché local y protocolo de diccionario»Las colecciones y las firmas son instantáneas memoizadas por wrapper. Una modificación externa del objeto o de su clase no refresca los resultados automáticamente. Las operaciones de escritura de este wrapper vacían su propia caché; otros wrappers del mismo objeto conservan sus instantáneas. No almacena nada en disco.
clearCache
Sección titulada «clearCache»def clearCache(self) -> None: ...Vacía todas las entradas y devuelve None; el próximo acceso vuelve a analizar los miembros.
reflected.getAttributes()service.title = "Revenue"assert reflected.getAttribute("title") == "Sales"reflected.clearCache()assert reflected.getAttribute("title") == "Revenue"__setitem__
Sección titulada «__setitem__»def __setitem__(self, key: str, value: object) -> None: ...Guarda value bajo key en la caché y devuelve None.
reflected["custom:note"] = "diagnostic"__getitem__
Sección titulada «__getitem__»def __getitem__(self, key: str) -> object | None: ...Devuelve una entrada, o None si no existe; no lanza KeyError.
assert reflected["custom:note"] == "diagnostic"assert reflected["custom:missing"] is None__contains__
Sección titulada «__contains__»def __contains__(self, key: str) -> bool: ...Comprueba pertenencia de key en la caché, no la existencia de atributos.
assert "custom:note" in reflected__delitem__
Sección titulada «__delitem__»def __delitem__(self, key: str) -> None: ...Elimina la entrada si existe; un nombre ausente no falla. Devuelve None.
del reflected["custom:note"]del reflected["custom:missing"]Usa prefijos propios para entradas auxiliares: escribir en claves internas como attributes o methods altera las lecturas del wrapper.
Inyección de dependencias
Sección titulada «Inyección de dependencias»No registres un wrapper genérico sin indicar qué objeto refleja. En un controlador u otro componente resuelto por Orionis puedes inyectar el servicio real y construir la reflexión con esa instancia. Las anotaciones de reflexión describen dependencias; no las inyectan por sí solas.
from app.services.report_service import ReportServicefrom orionis.http import JSONResponsefrom orionis.introspection import ReflectionInstance
class DiagnosticsController: async def __call__(self, reports: ReportService) -> JSONResponse: reflected = ReflectionInstance(reports) return JSONResponse({ "class": reflected.getModuleWithClassName(), "methods": reflected.getPublicMethods(), })El contrato de este wrapper es IReflectionInstance, importable desde orionis.introspection.instances.contracts.reflection. No elimina la necesidad de indicar el objeto objetivo: para inyectar un wrapper concreto debes proporcionar una instancia o una fábrica configurada para ese objetivo mediante tu proveedor.