定制 free-elephants/di 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

free-elephants/di

Composer 安装命令:

composer require free-elephants/di

包简介

IoC, constructor dependency injection

README 文档

README

Build Status codecov Installs Releases

Configure less. Do more.

Framework-agnostic Dependency Injection tool and PSR-11 implementation provider.

Requirements

PHP 7.4|8+

Installation

composer require free-elephants/di

Usage

Your entry php script (index.php or some background-job runner)

$components = require 'components.php';
$di = (new \FreeElephants\DI\InjectorBuilder)->buildFromArray($components);
$app = $di->createInstance(\YourApplication::class);
$app->run();

Your components.php file with dependencies description should look like this:

<?php

return [
    'instances' => [
        \PDO::class => new \PDO(getenv('DB_DNS'), getenv('DB_USER'), getenv('DB_PASS')),
    ],
    'register' => [
        \YourApplication::class,
        \ControllerFactory::class,
        \SomeService::class,
        \AnotherService::class,
        \Psr\Log\LoggerInterface::class => \Symfony\Component\Console\Logger\ConsoleLogger::class,
    ],
    'callable' => [ 
        // if function provided as key value
        // first argument passed to callable is psr container
        // second is key
        Foo::class => function(\Psr\Container\ContainerInterface $container, string $key) {
           return (new Foo())->setSomething($container->get('something'));
        },
        // if array provided as key value
        // first argument passed to callable is psr container
        // remaining element as ...args tail
        Bar::class => [ // array where first element is callable, other is values for last arguments
            function(\Psr\Container\ContainerInterface $container, $firstArg, string $secondArg) {
                return new Bar($firstArg, $secondArg);
            },
            100,
            500,
        ],       
    ],
    'loggers' => [
       // For suitable logger injections use map, where keys are your services, that implement LoggerAwareInterface
       // and value is logger instances or callable with logic for instantiate it. 
       LoggerAwareClass::class        => $logger,
       AnotherLoggerAwareClass::class => fn(\Psr\Container\ContainerInterface $container) => new \Psr\Log\NullLogger(),
    ],   
];

The main idea: all your components should expect all dependencies as constructor arguments. All other work entrust to Injector. You do not have to want to instantiate any classes directly in your code. Your must inject some factories instead.

Override Components by Environments

<?php
// getenv('ENV') -> 'test'
$components = (new \FreeElephants\DI\EnvAwareConfigLoader(__DIR__ . '/config', 'ENV'))->readConfig('components');
$di = (new \FreeElephants\DI\InjectorBuilder)->buildFromArray($components);

EnvAwareConfigLoader load config/components.php and merge it with config/components.test.php if it exists.

Options:

allowNullableConstructorArgs

Default value is false.

allowInstantiateNotRegisteredTypes

Default value is false. When you set it true, you can register only specific interfaces instances. All final typed dependency will be lazy-instantiated by chain!

useIdAsTypeName

Default value is true.

enableLoggerAwareInjection

Default value is false.

Allow to set LoggerInterface into LoggerAwareInterface instances after constructing, or use loggers map if type present.

Conception

[In Russian] Простейшее внедрение зависимостей через конструктор для PHP

В ООП можно выделить две большие группы классов по их ответственности: сущности и сервисы.

Сущности содержат данные и методы для работы с ними. Они чаще всего обладают состоянием и требуются во множестве экзепляров, создаваемых во время исполнения программы. Например:

  • доменные объекты (например Entities в контексте Doctrine, Models у Propel)
  • Value Objects
  • объекты для передачи данных (Data Transfer Objects)
  • Request / Response из PSR 7

Сервисы отвечают за всё остальное:

  • обрабатывают запрос пользователя (контроллеры, команды)
  • оперируют сущностями
  • обеспечивают коммуникацию между компонентами системы
  • инстанцируют другие сущности и сервисы (фабрики, локаторы)
  • предоставляют прикладную функциональность (протоколы, хранилища, роутинг)

Сервис часто требуются в единственном экземпляре, и, редко меняет собственное состояние во время исполнения. Сервисы могут быть описаны до этапа исполнения, например в статическом файле, и быть получены в коде по требованию, или созданы единожды при запуске приложения.

Сущности не должны зависеть от сервисов. В то время, как сервисы наоборот — часто оперируют экземплярами сущностей. При этом сервисы могут использовать другие сервисы.

Наиболее явный и надёжный способ внедрения зависимостей, это инъекция в конструктор:

  • нельзя создать экземпляр неготовый к использованию
  • зависимости класса обозначены контрактом в одном месте

Type Hinting и рефлексия в php позволяют собрать готовый к использованию сервис на основе сигнатуры его конструктора, без лишних конфигурационных файлов и магии. Такой подход использован в free-elephants/di. Этот способ хорошо поддерживает рефакторинг, т.к. используется только нативный php-код, не требует статического описания зависимостей в yml, xml или аннотациях.

free-elephants/di 适用场景与选型建议

free-elephants/di 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 19.96k 次下载、GitHub Stars 达 4, 最近一次更新时间为 2017 年 03 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 free-elephants/di 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 free-elephants/di 我们能提供哪些服务?
定制开发 / 二次开发

基于 free-elephants/di 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 19.96k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 5
  • 点击次数: 18
  • 依赖项目数: 2
  • 推荐数: 5

GitHub 信息

  • Stars: 4
  • Watchers: 2
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-2-Clause
  • 更新时间: 2017-03-18