VOOZH about

URL: https://deepwiki.com/hypervel/config/4-architecture-overview

⇱ Architecture Overview | hypervel/config | DeepWiki


Loading...
Menu

Architecture Overview

This document explains the high-level architecture of the hypervel/config system, describing how components are organized into layers, how they interact during the application lifecycle, and how configuration data flows from various sources into a unified repository accessible at runtime.

For detailed information about individual components, see Core Components. For specifics on the configuration loading algorithms, see Configuration Loading System.

System Layers

The configuration system is organized into five distinct architectural layers, each with specific responsibilities:


Diagram: System Layer Architecture

LayerComponentsResponsibilities
Package Definitioncomposer.jsonDeclares package metadata, dependencies, and Hyperf integration points via extra.hyperf.config
BootstrapConfigProvider, ProviderConfigRegisters the configuration factory with the DI container; discovers and merges configurations from external providers
FactoryConfigFactoryOrchestrates the configuration loading process by coordinating between provider configs, file-based configs, and the merging strategy
StorageRepository, Contracts\RepositoryStores the unified configuration array and provides type-safe access methods
Accessconfig() functionProvides convenient global access to the configuration repository

Sources: composer.json1-47 src/ConfigProvider.php src/ProviderConfig.php1-169 src/ConfigFactory.php1-66 src/Repository.php1-255

Application Lifecycle Phases

The configuration system operates across three distinct phases during the application lifecycle:


Diagram: Configuration System Lifecycle Sequence

Phase 1: Bootstrap

During application bootstrap, the Hyperf framework scans for service providers by reading the extra.hyperf.config entry in composer.json. The ConfigProvider class is invoked and registers ConfigFactory as the implementation for Hyperf\Contract\ConfigInterface in the dependency injection container.

Sources: composer.json39-42 src/ConfigProvider.php

Phase 2: Configuration Loading

When application code first requests a ConfigInterface instance (either explicitly or via the config() function), the DI container invokes ConfigFactory::__invoke(). This triggers the configuration loading process:

  1. Provider Discovery: ProviderConfig::load() discovers configurations from Composer packages
  2. Provider Merging: External configurations are merged using sophisticated logic
  3. File Loading: The factory loads config/hyperf.php and scans config/autoload/
  4. Final Merge: All sources are merged using ProviderConfig::mergeTwo()
  5. Repository Creation: A Repository instance is created with the merged configuration

Sources: src/ConfigFactory.php13-34 src/ProviderConfig.php26-54

Phase 3: Runtime Access

After initialization, application code accesses configuration through the Repository instance. The repository provides both simple access via the get() method and type-safe access via specialized methods like string(), integer(), etc.

Sources: src/Repository.php41-48 src/Functions.php

Component Interaction Map

The following diagram shows how key classes interact, using their actual class names and method signatures:


Diagram: Component Interaction with Method Signatures

Key Interactions

FromToMethod/MechanismPurpose
DI ContainerConfigProvider__invoke()Retrieve factory registrations
DI ContainerConfigFactory__invoke(ContainerInterface $container)Create configuration repository
ConfigFactoryProviderConfigProviderConfig::load()Retrieve provider configurations
ProviderConfigHyperf\Support\ComposerComposer::getMergedExtra()Discover package metadata
ConfigFactoryRepositorynew Repository($merged)Instantiate configuration store
config() functionRepositoryvia ApplicationContext::getContainer()->get()Resolve configuration instance

Sources: src/ConfigProvider.php src/ConfigFactory.php13-34 src/ProviderConfig.php26-54 src/Repository.php26-28

Configuration Data Flow

Configuration data flows through the system from multiple sources, undergoing transformations and merges before reaching the final repository:


Diagram: Configuration Data Flow Pipeline

Data Transformation Pipeline

  1. Source Discovery

    • ProviderConfig uses Composer::getMergedExtra() to discover package configurations from composer.json extra fields
    • Three discovery points: hyperf.config, hypervel.config, and hypervel.providers
    • Packages listed in dont-discover directives are filtered out
  2. Provider Loading

    • ProviderConfig::loadProviders() processes discovered provider classes
    • Invokes ServiceProvider::getProviderConfig() for provider classes
    • Calls __invoke() method for invokable classes
    • Returns arrays of configuration data
  3. Merging Strategy

    • Provider configurations are merged first using ProviderConfig::merge()
    • File-based configurations are loaded separately by ConfigFactory
    • All sources undergo final merge via array_reduce() with ProviderConfig::mergeTwo()
    • Merge precedence: providers (lowest) → root config → autoload configs (highest)
  4. Storage

    • The final merged array is passed to Repository constructor
    • Stored in Repository->items protected property
    • Accessed at runtime via Arr utility methods with dot notation support

Sources: src/ProviderConfig.php26-54 src/ProviderConfig.php56-75 src/ConfigFactory.php22-33 src/Repository.php26-28

Runtime Access Architecture

At runtime, application code accesses configuration through multiple access patterns, all backed by the same Repository instance:


Diagram: Runtime Access Patterns and Resolution

Access Methods

PatternCode ExampleResolution Path
Global Functionconfig('app.name')config()ApplicationContextContainerRepository::get()
Dependency Injection__construct(Repository $config)Container auto-wires Repository instance
Array Access$config['app.name']Repository::offsetGet()Repository::get()
Type-Safe Access$config->string('app.name')Repository::string()Repository::get() + type validation

All access patterns ultimately invoke Repository::get(), which uses Hyperf\Collection\Arr::get() to access the $items array with support for dot notation (e.g., 'app.name' accesses $items['app']['name']).

Sources: src/Functions.php src/Repository.php41-48 src/Repository.php73-84 src/Repository.php220-233

Key Architectural Decisions

Separation of Concerns

The architecture clearly separates discovery, loading, merging, storage, and access concerns into distinct classes:

  • Discovery: ProviderConfig handles all provider discovery logic
  • Orchestration: ConfigFactory coordinates the overall loading process
  • Storage: Repository manages the configuration data structure
  • Access: Global function and DI provide flexible access patterns

Lazy Initialization

Configuration loading is deferred until first access via the factory pattern. The ConfigFactory is only invoked when ConfigInterface is requested from the DI container, avoiding unnecessary work during bootstrap if configuration is never accessed.

Sources: src/ConfigFactory.php13-34

Static Caching

ProviderConfig::load() caches discovered provider configurations in a static property to avoid repeated discovery overhead. The cache can be cleared via ProviderConfig::clear() if needed during testing or dynamic reloading scenarios.

Sources: src/ProviderConfig.php26-30

Unified Merge Algorithm

Both provider configurations and file-based configurations use the same ProviderConfig::mergeTwo() algorithm, ensuring consistent merge behavior across all configuration sources. This handles numeric keys (deduplication), string keys (recursive merge), and special cases like PriorityDefinition objects.

Sources: src/ProviderConfig.php145-168 src/ConfigFactory.php27-31

Framework Abstraction

The Contracts\Repository interface extends Hyperf\Contract\ConfigInterface, allowing the hypervel implementation to be a drop-in replacement for Hyperf's default configuration system while adding additional functionality like type-safe getters and callback hooks.

Sources: src/Contracts/Repository.php src/Repository.php14