Resumen de arquitectura
Modelo de capas
DAF sigue una arquitectura en capas. Seis de sus módulos separan sus contratos en un paquete Abstractions, para que el código de tu app pueda depender solo de interfaces:
┌─────────────────────────────────────────┐
│ Tu Aplicación │
├─────────────────────────────────────────┤
│ Application │ Hosting │ MediatR │ ← Composición
├──────────┬────┴──────┬────┴────┬────────┤
│ Logging │ Config │ DI │ NNLog │ ← Servicios
├──────────┴───────────┴─────────┴────────┤
│ Commons · Rtti · Threading │ ← Fundación
└─────────────────────────────────────────┘
Patrón Abstractions
Configuration, DependencyInjection, Hosting, Logging, MediatR y SQLCute se distribuyen como par:
| Paquete | Rol |
|---|---|
Daf.X.Abstractions |
Solo interfaces — sin implementación |
Daf.X |
Implementación concreta + helpers de registro |
El código de tu app depende solo de Abstractions. Las implementaciones son intercambiables en el composition root.
Flujo de dependencias
Application
└── Hosting
├── DependencyInjection
├── Configuration
└── Logging
└── NNLog (proveedor)
Testing con MiniSpec
MiniSpec es independiente del resto del stack. Puede testear cualquier código Delphi usando specs estilo Gherkin:
Feature('Calculadora')
.UseWorld<TCalculatorWorld>
.Scenario('Sumar dos números')
.Given('tengo una calculadora', procedure(World: TCalculatorWorld)
begin
World.Calculator := TCalculator.Create;
end)
.When('sumo 2 y 3', procedure(World: TCalculatorWorld)
begin
World.Calculator.Add(2, 3);
end)
.&Then('el resultado es 5', procedure(World: TCalculatorWorld)
begin
Expect(World.Calculator.Result).ToEqual(5);
end);&Then lleva el ampersand porque then es palabra reservada de Delphi, y UseWorld<T> va primero porque es lo que le da a cada paso su World. La versión que compila está en src/MiniSpec/samples/CalculatorSpecs.
Ver el módulo MiniSpec para la guía completa.