Variables Dinámicas

Una variable dinámica es una definición segura en cuanto a tipos de un valor configurable que puede ser sobrescrito en tiempo de ejecución. Las variables dinámicas se definen utilizando el Marco de Reglas.DynamicValueLibrary concepto y generar a Java código que se integra con el DynamicExpressionRegistry.

Descripción general

Las variables dinámicas proporcionan una forma de externalizar la configuración de sus reglas de negocio. Cada variable dinámica tiene:

  • Un nombre del modelo- identifica cuál MPS modelar la variable a la que pertenece

  • Un nombre de variable- el nombre único dentro del modelo

  • Un tipo- the Java clase que representa el tipo de valor (primitivos o listas)

  • Un valor predeterminado- utilizado cuando no se proporciona una anulación de configuración

Cuando su MPS el modelo se compila, las variables dinámicas generan un DynamicVariable<T> registro que encapsula estos metadatos.

Seguridad de Tipo

Las variables dinámicas son de tipo fuerte. Los tipos soportados son:

  • Tipos primitivos:`Number`,String,Boolean

  • Tipos de lista:`List<Number>`,List<String>,List<Boolean>

Este tipo de seguridad se aplica tanto en tiempo de compilación (en el código generado) como en tiempo de ejecución (al cargar los valores de configuración).

Validación de Tipo en Tiempo de Ejecución

Cuando se cargan las fuentes de configuración al inicio de la aplicación, el ConfigurableValuesManager valida que el tipo de cada valor de configuración coincida con el correspondiente DynamicVariable definición de tipo. Esta validación:

  • Ocurre al inicio- Los errores de configuración se detectan inmediatamente cuando la aplicación se carga.

  • Valida en actualizaciones de push- Las fuentes dinámicas que admiten actualizaciones en tiempo de ejecución también activan la validación.

  • Usos de la asignabilidad de tipos- Se aceptan subtipos (por ejemplo,ArrayList para List,Integer para Number)

  • Permite valores nulos- Null se considera válido y elude la verificación de tipos.

Si se detecta un desajuste de tipo, la aplicación falla rápidamente con un mensaje de error detallado:

java.lang.IllegalArgumentException: Type mismatch for configuration variable with key:
'paymentService_upperBound' - expected type java.lang.Integer but got java.lang.String

Esto asegura que los errores de configuración se detecten temprano en lugar de causar fallos en tiempo de ejecución en la lógica de negocio.

Formato Clave

Cada variable dinámica tiene una clave compuesta utilizada para búsquedas en el registro:

{modelName}_{variableName}

Por ejemplo, una variable llamada upperBound en un modelo llamado paymentService tendría la clave:

paymentService_upperBound

Este formato de clave se utiliza al configurar valores en HOCON archivos o registrándolos programáticamente.

Código Generado

Cuando usted define una variable dinámica en MPS, el generador de código crea un DynamicVariablesLibrary clase:

public class DynamicVariablesLib implements DynamicVariableLibrary {

    // Static variable definitions with defaults
    public static final DynamicVariable<Number> upperBound =
        new DynamicVariable<>(
            "paymentService",           // model name
            "upperBound",               // variable name
            Number.class,               // type
            BigInteger.valueOf(1000)    // default value
        );

    public static final DynamicVariable<List<String>> allowedCurrencies =
        DynamicVariable.ofList(
            "paymentService",
            "allowedCurrencies",
            String.class,
            Arrays.asList("USD", "EUR", "GBP")
        );

    // Singleton instance
    public static DynamicVariableLibrary INSTANCE = new DynamicVariablesLibrary();

    // Instance field containing all variables
    private final List<DynamicVariable<?>> dynamicVariables;

    // Constructor initializes the list
    private DynamicVariablesLib() {
        dynamicVariables = new ArrayList<>();
        dynamicVariables.add(upperBound);
        dynamicVariables.add(allowedCurrencies);
    }

    @Override
    public List<DynamicVariable<?>> getDynamicVariables() {
        return dynamicVariables;
    }
}

El código generado también hace referencia a DynamicVariableResolver.resolve() para recuperar el valor actual en tiempo de ejecución.

DynamicVariable Registro

El DynamicVariable<T> el registro se define como:

public record DynamicVariable<T>(
    String modelName,
    String name,
    Class<T> rawType,
    Class<?> elementType,
    T defaultValue
) {
    // Key generation
    public String key() {
        return modelName + "_" + name;
    }

    // Factory for list types
    public static <E> DynamicVariable<List<E>> ofList(
        String modelName,
        String name,
        Class<E> elementType,
        List<E> defaultValue
    ) { ... }
}

Flujo de Resolución

Cuando el código generado necesita un valor de variable dinámica:

  1. DynamicVariableResolver.resolve(variable) se llama

  2. El resolutor verifica primero un valor con alcance de entidad (si existe un contexto de procesamiento)

  3. Vuelve al registro global

  4. Devuelve el valor predeterminado si no se encuentra ninguna anulación.

  5. Convierte el valor al apropiado KernelF tipo