VOOZH about

URL: https://deepwiki.com/hypervel/config/9.1-custom-configuration-providers

⇱ Custom Configuration Providers | hypervel/config | DeepWiki


Loading...
Menu

Custom Configuration Providers

Purpose and Scope

This document explains how to create custom configuration providers that contribute configuration data to the application during the bootstrap phase. Configuration providers allow packages and components to register their own configuration values that are automatically discovered and merged into the application's configuration repository.

This page covers the two provider types supported by the system (ServiceProvider subclasses and invokable classes), how to register them in composer.json, and the discovery mechanism that loads them. For information about how provider configurations are merged together, see Configuration Merging Strategies. For the overall loading process, see Provider Config Discovery and Merging.


Configuration Provider Types

The system supports two distinct types of configuration providers, both processed by the ProviderConfig::loadProviders() method:

Provider TypeBase Class/InterfaceMethod CalledUse Case
ServiceProvider-basedHypervel\Support\ServiceProvidergetProviderConfig() static methodFull-featured service providers with configuration contribution
InvokableAny class with __invoke()__invoke() instance methodLightweight, configuration-only providers

Sources: src/ProviderConfig.php56-75


ServiceProvider-Based Configuration Providers

Overview

ServiceProvider-based configuration providers extend the Hypervel\Support\ServiceProvider class and implement a static getProviderConfig() method that returns a configuration array. This approach is suitable for packages that need to provide configuration alongside other service provider functionality.

Implementation Structure


Diagram: ServiceProvider-Based Configuration Provider Flow

Sources: src/ProviderConfig.php63-67

Creating a ServiceProvider Configuration Provider

A ServiceProvider-based configuration provider must:

  1. Extend Hypervel\Support\ServiceProvider
  2. Implement a static getProviderConfig() method
  3. Return an associative array with configuration data

The getProviderConfig() method is called statically during the discovery process at src/ProviderConfig.php64 which means it must not rely on instance state.

Example Structure:


Sources: src/ProviderConfig.php63-67


Invokable Configuration Providers

Overview

Invokable configuration providers are simple classes that implement an __invoke() method. This approach is lightweight and suitable for packages that only need to contribute configuration without additional service provider functionality.

Implementation Structure


Diagram: Invokable Configuration Provider Flow

Sources: src/ProviderConfig.php69-71

Creating an Invokable Configuration Provider

An invokable configuration provider must:

  1. Implement an __invoke() method
  2. Return an associative array with configuration data
  3. Have a no-argument constructor (or no explicit constructor)

The provider is instantiated and invoked at src/ProviderConfig.php70 so the constructor must not require dependencies.

Example Structure:


Sources: src/ProviderConfig.php69-71


Registering Configuration Providers in composer.json

Discovery Keys

Configuration providers must be registered in a package's composer.json file under the extra section. The system recognizes three discovery keys:

KeyPurposeCompatibility
extra.hyperf.configHyperf framework compatibilityStandard Hyperf packages
extra.hypervel.configHypervel-specific configurationHypervel packages
extra.hypervel.providersExplicit provider registrationHypervel packages

All three keys are collected and merged during discovery at src/ProviderConfig.php37-42

Registration Example


Multiple Providers

Providers can be registered as:

  • A single string: "config": "Vendor\\Package\\ConfigProvider"
  • An array of strings: "config": ["Provider1", "Provider2"]

The system wraps single values into arrays using Arr::wrap() at src/ProviderConfig.php39-41

Sources: src/ProviderConfig.php37-44


Provider Discovery Process

Discovery Sequence


Diagram: Configuration Provider Discovery Sequence

Sources: src/ProviderConfig.php26-54 src/ProviderConfig.php56-75

Discovery Algorithm

The provider discovery process follows these steps:

  1. Cache Check - Return cached result if $providerConfigs is already populated src/ProviderConfig.php28-30

  2. Package Filtering - Build ignore list from dont-discover configuration src/ProviderConfig.php32-35

    • If * is in ignore list, return empty array immediately
    • Otherwise, continue with discovery
  3. Extract Provider Lists - Collect providers from all packages src/ProviderConfig.php37-44

    • Read Composer::getMergedExtra() to get all package metadata
    • Extract hyperf.config, hypervel.config, and hypervel.providers keys
    • Merge arrays from all three keys per package
  4. Filter Packages - Remove ignored packages from the list src/ProviderConfig.php45-49

  5. Flatten and Load - Process the provider array src/ProviderConfig.php51-53

    • Flatten multi-dimensional array into single list
    • Pass to loadProviders() for instantiation

Sources: src/ProviderConfig.php26-54

Provider Loading Algorithm

The loadProviders() method processes each provider class:


Diagram: Provider Loading Algorithm

Sources: src/ProviderConfig.php56-75

The loading logic at src/ProviderConfig.php59-72 performs these checks for each provider:

  1. Validation - Skip if not a string or class doesn't exist
  2. ServiceProvider Check - If subclass of ServiceProvider, call static getProviderConfig()
  3. Invokable Check - If has __invoke() method, instantiate and invoke
  4. Collection - Add returned configuration to $providerConfigs array

After loading all providers, the method merges them using merge(...$providerConfigs) at src/ProviderConfig.php74

Sources: src/ProviderConfig.php56-75


Package Filtering with dont-discover

Filtering Mechanism

Packages can be excluded from configuration discovery using the dont-discover directive. This is useful for:

  • Disabling problematic providers during development
  • Excluding test packages from production
  • Preventing conflicts between providers
  • Optimizing bootstrap performance

The filtering is implemented in packagesToIgnore() at src/ProviderConfig.php77-88

Configuration Sources

The ignore list is compiled from two sources:

  1. Package-level - From merged extra configuration: Composer::getMergedExtra('hypervel')['dont-discover']
  2. Project-level - From root composer.json: extra.hypervel.dont-discover

Both lists are merged together at src/ProviderConfig.php87

Wildcard Support

Setting dont-discover to ["*"] disables all provider discovery at src/ProviderConfig.php33-35 causing load() to return an empty array immediately.

Example Configuration


Sources: src/ProviderConfig.php32-35 src/ProviderConfig.php77-88


Provider Configuration Structure

Common Configuration Keys

Configuration providers typically return arrays with these keys:

KeyTypePurposeExample
dependenciesarrayDependency injection bindings[Interface::class => Implementation::class]
commandsarrayConsole command classes[CommandClass::class]
listenersarrayEvent listener mappings[Event::class => [Listener::class]]
annotationsarrayAnnotation scan configuration['scan' => ['paths' => [__DIR__]]]
publisharrayPublishable assets[['id' => 'config', 'source' => '...']]

Dependencies with PriorityDefinition

The dependencies key receives special handling during merging at src/ProviderConfig.php113-128 When a dependency uses PriorityDefinition objects, the merge process preserves priority-based ordering by calling $depend->merge($value) instead of simple array replacement.

For detailed information about this behavior, see Priority Definitions and Dependencies.

Sources: src/ProviderConfig.php113-128


Best Practices

Choosing Provider Type

Use ServiceProvider WhenUse Invokable When
Provider has multiple responsibilitiesOnly providing configuration
Need lifecycle hooks (boot, register)Simple, stateless configuration
Part of larger service provider patternStandalone configuration package
Configuration depends on runtime stateConfiguration is static

Configuration Organization

  1. Group Related Configuration - Keep related settings under nested keys:

    
    
  2. Avoid Top-Level Pollution - Namespace configuration under package name to prevent conflicts

  3. Document Required Configuration - Include comments or README explaining expected structure

  4. Use Sensible Defaults - Provide working defaults; users override as needed

Performance Considerations

  1. Static Configuration - Keep getProviderConfig() and __invoke() stateless for caching efficiency
  2. Minimal Logic - Avoid expensive operations; discovery happens on every bootstrap
  3. Lazy Loading - Don't instantiate heavy dependencies in provider constructors
  4. Cache Awareness - Remember that load() caches results in static property src/ProviderConfig.php28-30

Sources: src/ProviderConfig.php28-30 src/ProviderConfig.php56-75


Provider Lifecycle Summary


Diagram: Complete Provider Lifecycle

Sources: src/ProviderConfig.php26-75


Related Topics

Refresh this wiki

On this page