Skip to content

Qué API debe usar cada consumidor ​

Índice · Planes

La biblioteca tiene una superficie cotidiana y una superficie de extensión. Ambas llegan al mismo evaluador, pero no requieren el mismo conocimiento. Empieza por la primera y pasa a la segunda cuando el problema lo exija.

Validación cotidiana ​

Para un formulario o un candidato de aplicación, normalmente basta con conocer:

csharp
Validation.For<T>()
Validation.For<T, TContext>()
Field(...)
Required(...)
Email(...)
Must(...)
MustAsync(...)
Sequence(...)
Build()
Validate(...) / ValidateAsync(...)
ValidationReport

Ejemplo:

csharp
var plan = Validation.For<Customer, CustomerContext>()
    .Field(x => x.Email, field => field.Sequence(sequence => sequence
        .Required("El correo es obligatorio.")
        .Email("El correo no es válido.")
        .MustAsync((email, context, token) => context.IsAvailableAsync(email!, token),
            "El correo ya está registrado.")))
    .Build();

var report = await plan.ValidateAsync(customer, context);

El consumidor solo decide tres cosas: qué campo validar, qué orden necesita y qué mensaje mostrar. El builder genera identidades internas y los diagnósticos reciben códigos predeterminados, que pueden fijarse con el parámetro code.

Reglas reutilizables ​

Usa ValidationRule.For, ForAsync, WithEvidence o WithEvidenceAsync cuando una regla:

  • aparece en más de un plan;
  • necesita una identidad lógica reutilizable además del código público;
  • necesita evidencia tipada para el mensaje;
  • pertenece a un catálogo de reglas de la aplicación o del dominio;
  • debe recibir un contexto propio.
csharp
public static class CustomerRules
{
    public static ValidationDefinition<string?, CustomerContext> UniqueEmail { get; } =
        ValidationRule.ForAsync<string?, CustomerContext>(
            "email.unique",
            (email, context, token) => context.IsAvailableAsync(email!, token),
            "customer.email.duplicate",
            "El correo ya está registrado.");
}

Después se incorpora con .Add(CustomerRules.UniqueEmail) dentro de una secuencia. La secuencia establece la dependencia; la definición no captura el contexto de un formulario concreto.

Contratos para autores de reglas ​

Implementa IRule<T> cuando quieres publicar una condición síncrona reutilizable en platform.rules. Implementa IAsyncRule<T> para una condición asíncrona sin contexto y IContextRule<T, C> para una condición asíncrona que recibe contexto por ejecución.

Puedes pasar IRule<T> directamente a ValidationRule.For. IAsyncRule<T> e IContextRule<T, C> se pasan a ValidationRule.ForAsync. El consumidor no necesita construir RuleDefinition manualmente.

Motor avanzado ​

Usa directamente RuleDefinition, RuleNode, RuleTree, RuleEvaluator y RuleEvaluationOptions cuando necesites:

  • construir árboles fuera del builder fluido;
  • inspeccionar estados Skipped y razones de omisión;
  • conservar una traza completa;
  • adaptar una composición a otra infraestructura;
  • controlar identidades de aparición de forma explícita.

El motor avanzado produce RuleEvaluation, que es neutral y no contiene mensajes. Para una API de aplicación, suele ser más conveniente construir un ValidationPlan, porque este asocia diagnósticos y devuelve ValidationReport.

Formularios ​

Añade FormValidationSession<T, C> cuando necesites debounce, cancelación o publicación en un hilo de UI. No hace falta usarla para validar una petición única en un endpoint.

Usa Options y OptionsSession para cargar opciones dependientes. La sesión de opciones carga datos; las reglas del plan siguen siendo responsables de verificar que la selección sea válida.

Regla de decisión ​

PreguntaAPI
¿Solo necesito un booleano?IRule<T> o IAsyncRule<T>
¿Necesito mensaje y código?ValidationRule
¿Necesito componer campos?ValidationBuilder
¿Necesito consultar un servicio?Validation.For<T, C>() y MustAsync
¿Necesito evidencia para el mensaje?WithEvidence
¿Necesito proteger una consulta con reglas previas?Sequence
¿Necesito una evaluación para la UI?FormValidationSession
¿Necesito conocer cada nodo ejecutado?RuleEvaluator con Trace

Los tipos avanzados siguen siendo públicos para permitir extensiones, pero no forman parte del primer recorrido de aprendizaje.

Uso personal limitado. Uso comercial sujeto a autorización escrita.