Skip to main content
LibreDTE Core is built on a modern, modular architecture designed for flexibility and maintainability. The library leverages industry-standard components while providing a clean abstraction layer for electronic invoicing in Chile.

Core Architecture Layers

The architecture consists of three main layers:

Application Layer

The Application class extends MicroKernel and serves as the entry point

Package Layer

Modular packages like billing encapsulate related functionality

Component Layer

Fine-grained components within packages handle specific tasks

MicroKernel Foundation

LibreDTE Core extends the Derafu MicroKernel, a lightweight kernel that provides:
  • Dependency injection container management
  • Environment configuration (dev, prod, test)
  • Service configuration loading
  • Compiler pass registration
Application.php
namespace libredte\lib\Core;

use Derafu\Kernel\MicroKernel;
use libredte\lib\Core\Contract\ApplicationInterface;

final class Application extends MicroKernel implements ApplicationInterface
{
    protected function configure(
        ContainerConfigurator $configurator,
        ContainerBuilder $container
    ): void {
        // Load configuration
        $configurator->import(__DIR__ . '/../config/services.yaml');

        // Add compiler passes
        $container->addCompilerPass(
            new ServiceProcessingCompilerPass('libredte.lib.')
        );
        $container->addCompilerPass(
            new ServiceConfigurationCompilerPass('libredte.lib.')
        );
    }
}
The MicroKernel approach provides a lightweight alternative to full frameworks, focusing solely on dependency injection and service management without unnecessary overhead.

Singleton Pattern (Optional)

While the library fully supports dependency injection, it also provides a singleton instance for simpler use cases:
use libredte\lib\Core\Application;

// Get singleton instance
$app = Application::getInstance('dev', true);

// Access services
$billingPackage = $app->getPackageRegistry()->getBillingPackage();
The singleton pattern is provided for convenience but is not recommended when using LibreDTE within a dependency injection container. Always prefer constructor injection in modern applications.

Service Configuration

All services are configured in config/services.yaml with:
Services are automatically wired based on type hints:
services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

Compiler Passes

Two custom compiler passes enhance the container:
Processes services with the libredte.lib. prefix, enabling custom service manipulation during container compilation.
Handles configuration merging and validation for LibreDTE services, ensuring proper setup before runtime.

Environment Management

The application supports multiple environments:
  • dev: Development with full debugging
  • prod: Production-optimized with caching
  • test: Testing environment with fixtures
// Specify environment and debug mode
$app = new Application(
    environment: 'prod',
    debug: false
);

Key Design Principles

Dependency Injection First

All components receive dependencies via constructor injection

Interface-Based Design

Programming to interfaces enables flexibility and testability

Lazy Loading

Services are instantiated only when needed

Strategy Pattern

Document-specific logic uses swappable strategies

Next Steps

Packages & Components

Learn about the package and component structure

Dependency Injection

Deep dive into the DI container usage

Build docs developers (and LLMs) love