fogio/container

Fogio 依赖注入容器

dev-master 2016-12-10 23:03 UTC

This package is not auto-updated.

Last update: 2024-09-23 13:47:18 UTC


README

依赖注入容器;IoC(控制反转);快速;简单;无自动注入;静态、动态、懒加载服务定义

安装

composer require fogio/container

用法

静态定义

<?php

use Fogio\Container;

class App extends Container
{
    protected function _db() // service name is prefixed with `_`
    {
        return $this->db = new Pdo('mysql:host=localhost;dbname=test'); // shared
    }

    protected function _mailer()
    {
        return Mailer::class; // shared, setDefaultShared(true) by default
    }

    protected function _newsletter()
    {
        return new (Newsletter()) // non shared
            ->setMailer($this->mailer) // injection
            ->setDb($this->db)
    }
}

$app = new App();
$app->newsletter->send();

通过 __invoke 的动态定义

<?php

use Fogio\Container;

$app = new Container();
$app([
    'newsletter' => function ($c) {
        return $c->db = new Pdo('mysql:host=localhost;dbname=test'); // shared
    },
    'mailer' => Mailer::class, // shared
    'newsletter' => function ($c) {
        return new (Newsletter()) // non shared
            ->setMailer($c->mailer) // injection
            ->setDb($c->db)
    },
]);
$app->newsletter->send();

动态定义具有更高的优先级

<?php

use Fogio\Container;

class App extends Container
{
    protected function _newsletter()
    {
        return NewsletterA::class;
    }
}

$app = new App();
$app([
    'newsletter' => function ($c) {
        return NewsletterB::class; // shared
    },
]);
echo get_class($app->newsletter); // NewsletterB

使用特性

<?php

use Fogio\ContainerTrait;

class App
{
    use ContainerTrait;
}

使用 _factory 扩展容器中的每个服务

<?php

use Fogio\Container;

$validators = new Container();
$validators([
    'notEmpty' => NotEmpty::class,
    'email'    => Email::class,
    '_factory' => function($service, $name, $container) {
        if ($service instanceof TranslatorAwareInterface) {
            $service->setTranslator(new Translator());
        }

        return $service;
    }
]);

_factory 即使服务未定义也会被调用

<?php

use Fogio\Container;

$services = new Container();
$services([
    '_factory' => function($service, $name, $container) {
        if ($service == null) {
            $service = new DefaultService();
        }

        return $service;
    }
]);

使用 _init 懒加载动态服务定义

<?php

use Fogio\Container;

class Validators extends Container implements LostInToughtInterface
{
    protected function __init()
    {
        configure($this);
    }
}

$validators = new Validators();
// $validators instanceof LostInToughtInterface === true
// services are not defined yet

function configure($container) {
    $container([
        'notEmpty' => NotEmpty::class,
        'email'    => Email::class,
    ]);
}

// getting service from container  
$emailValidator = $validators->email;

// or checking if service is defined
isset($validators->email);

// calls the `_init` feature and configure the container

_init_factory 是保留的服务名称