-
-
Notifications
You must be signed in to change notification settings - Fork 1
Configuration
Опциональная загрузка определений из нескольких файлов (PHP, JSON, YAML, XML). Реализована отдельным сервисом ContainerConfigurator — контейнер можно по-прежнему собирать только через PHP API.
Формат по умолчанию — PHP (return [...]).
flowchart LR
subgraph sources [Источники]
F1[base.php]
F2[override.json]
F3[prod.xml priority]
end
sources --> CC[ContainerConfigurator]
CC --> Merge[ConfigurationMerger]
Merge --> Apply[ConfigurationApplicator]
Apply --> C[Container]
C --> Freeze[freeze опционально]
flowchart TD
L1[слой 1 order=0] --> M[merge]
L2[слой 2 priority=10] --> M
L3[слой 3 priority=100] --> M
M --> Winner{конфликт ключа}
Winner --> P1[priority параметра в элементе]
P1 --> P2[priority файла ConfigurationSource]
P2 --> P3[порядок в списке — последний]
P3 --> Final[итоговый config array]
<?php
use CloudCastle\DI\Configuration\ConfigurationSource;
use CloudCastle\DI\Configuration\ContainerConfigurator;
use CloudCastle\DI\Container;
$container = new Container();
$configurator = new ContainerConfigurator();
$configurator->configure($container, [
__DIR__ . '/config/base.php',
__DIR__ . '/config/override.json',
new ConfigurationSource(__DIR__ . '/config/prod.xml', priority: 100),
]);
$container->freeze();При конфликте одного и того же параметра:
-
priorityу параметра —['value' => 'x', 'priority' => 100]или XML-атрибутpriorityна элементе -
Приоритет файла —
new ConfigurationSource($path, priority: N)или ключpriorityв корне конфига - Порядок в списке источников — без явного приоритета побеждает последний файл
| Метод | Описание |
|---|---|
configure(ContainerInterface $container, array $sources): void |
loadMany() + apply()
|
loadMany(array $sources): array |
Загрузить и объединить без применения |
load(string $path): array |
Один файл |
apply(ContainerInterface $container, array $config): void |
Применить уже объединённый массив |
$sources — list<string|ConfigurationSource>.
| Расширение | Загрузчик | Зависимости |
|---|---|---|
.php |
PhpConfigurationLoader |
нет (по умолчанию) |
.json |
JsonConfigurationLoader |
ext-json |
.yaml, .yml
|
YamlConfigurationLoader |
ext-yaml (yaml_parse_file) |
.xml |
XmlConfigurationLoader |
ext-simplexml |
Без ext-yaml вызов load() для .yaml бросает ContainerException с подсказкой установить расширение.
PHP-конфиг может содержать callable (фабрики в services). JSON, YAML и XML — только декларативные данные.
Общая схема для PHP / JSON / YAML:
return [
'priority' => 10, // приоритет всего файла (опционально)
'register_attributes' => [ // пользовательские ServiceIdAttribute
My\InjectAttribute::class,
],
'autowiring' => [
'enabled' => true,
'parameter_name' => true,
'property' => true,
'method' => true,
],
'scan' => [
['directory' => '/path/to/src', 'namespace' => 'App\\'],
],
'services' => [
'app.env' => 'prod',
'logger' => ['class' => FileLogger::class, 'lazy' => true],
'key' => ['value' => 'x', 'priority' => 100],
],
'autowire' => [SomeClass::class],
'bind' => [LoggerInterface::class => FileLogger::class],
'aliases' => ['env' => 'app.env'],
'tags' => ['handlers' => ['handler.email', 'handler.sms']],
];- Скаляр или массив —
set($id, $value) -
['class' => FQCN, 'lazy' => true]—set($id, $container->lazy(FQCN)) -
id === class—autowire(FQCN); иначе —bind($id, FQCN)
register_attributes → autowiring → scan → services → autowire → bind → aliases → tags
Корневой элемент <container priority="…">. Секции: <services>, <aliases>, <bind>, <autowire>, <tags>, <scan>, <register_attributes>, <autowiring>.
Пример сервиса с классом и lazy:
<service id="logger" class="App\FileLogger" lazy="true"/>Параметр с приоритетом:
<service id="app.label" priority="100">from-xml</service>Autowire по имени класса в атрибуте:
<autowire>
<class name="App\Services\Clock"/>
</autowire>Передайте свой список в конструктор:
new ContainerConfigurator(
loaderRegistry: new ConfigurationLoaderRegistry([
new PhpConfigurationLoader(),
new JsonConfigurationLoader(),
// …
]),
);Реализуйте CloudCastle\DI\Contract\ConfigurationLoaderInterface.
После freeze() вызов configure() / apply() приведёт к ContainerException при попытке изменить определения (как и прямые set() / bind()).
Рекомендуемый порядок: configure() → freeze() в composition root.
-
Примеры bootstrap — PHP-конфиги и prod
freeze() -
Autowiring —
register_attributesи пользовательские attributes -
Справочник API —
ContainerConfigurator,registerAttribute()
CloudCastle DI · Репозиторий · Packagist · Releases · Discussions · Issues
Исходники Wiki — wiki/ в репозитории (синхронизация через Actions).
- Архитектура
- Быстрый старт
- Сравнение с PHP-DI, Symfony, Pimple — пошагово
- Примеры bootstrap
- Autowiring
- Конфигурация из файлов
- Сканирование классов
- Глобальный реестр
- Теги и декораторы
- call(), bind(), afterResolving
- Прототипы, alias и lazy
- Справочник API
- Фабрики и singleton
- Тестирование
- Тесты безопасности
- Нагрузка и производительность
- Анти-паттерны