sasa-b/container

具有 Laravel 风格的自动装配、接口/抽象类绑定和上下文绑定的轻量级依赖注入容器。遵循 PSR-11 标准。

1.0.1 2017-10-09 11:39 UTC

This package is auto-updated.

Last update: 2024-09-14 10:26:21 UTC


README

具有 Laravel 风格的自动装配、接口/抽象类绑定和上下文绑定的轻量级依赖注入容器。遵循 PSR-11 标准。

要使用此库,请克隆仓库或直接使用 composer 安装。

composer require sasa-b/container

使用示例

require '../vendor/autoload.php';

$container = new Foundation\Container\Container();`

绑定/注册服务

一个服务(绑定值)可以是类的字符串表示、一个返回对象实例的匿名函数,或是一个对象实例本身。如果您绑定一个对象实例本身,该服务将本质上作为单例使用,因为始终返回相同的实例。

$container->bind(Foo\Bar::class, Foo\Bar::class); 

$container->bind(Foo\Bar::class, function ($container) { 
   return new \Foo\Bar($container['Foo\Baz']);
   
}); 

$container->bind('Foo\Bar', FooBar::class); 

$container->bind(Foo\Bar::class, new \Foo\Bar());
单例
   $container->bind('Foo\Bar', FooBar::class)->share();
   
   //or
   
   $container->bind('Foo\Bar', FooBar::class);
   $container->share(Foo\Bar::class);
   
   $container->bind(Foo\Baz::class, Foo\Baz::class)->mapTo('baz');
   $container->share('baz');

将服务映射到键

为了方便,您可以将服务映射到键,并且有多种方法可以实现。

  1. 通过 mapTo 方法通过方法链
$container->bind(Foo\Bar::class, Foo\Bar::class)->mapTo('foo');
  1. 通过 key 方法
$container->key('foo', Foo\Bar::class);
  1. 直接使用 bind 语句
$container->bind('foo', function ($container) {
   return new Foo\Bar();
});

当您直接将服务绑定到 时,它们只能通过该 访问,并且这些服务不能用于 自动装配(通过类型提示注入),除非您绑定/注册的服务是类的字符串表示,在这种情况下,服务将自动映射到给定的

mapTokey 绑定/注册的服务可以通过键和它们的类名访问,因此它们可以用于自动装配。

绑定/注册多个服务

要一次性注册多个服务,您可以使用 register 方法或其别名 bindMany

$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->mapTo(['request', 'session', 'cookie', 'db']);

$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class
]);

$container->keys([
   'request' => Foundation\Request\Http::class,
   'session' => Foundation\Sessions\SessionManager::class,
   'cookie' => Foundation\Request\Cookie::class
]);
注册多个单例
/* Only those specified will be registered as singletons */
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->share(['session', 'db', Foundation\Core\Database::class]);

/* All will be registered as singletons */
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
])->share();
// or
$container->register([
    Foundation\Request\Http::class => Foundation\Request\Http::class,
    Foundation\Sessions\SessionManager::class => \Foundation\Sessions\SessionManager::class,
    Foundation\Request\Cookie::class => Foundation\Request\Cookie::class,
    'date' => \DateTime::class,
    Foundation\Core\Database::class => Foundation\Core\Database::class,
    Foundation\Database\QueryBuilder::class => (function ($c) {
        return new \Foundation\Database\PDOQuery($c['db']);
    })
], true);

抽象绑定

您还可以将服务绑定/注册到接口和抽象类。当与自动装配一起使用时,这些抽象绑定很方便,因为您可以使用抽象(抽象类和接口)进行类型提示,而不是具体实现。

$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\AbstractBaz::class, Foo\Baz::class);
上下文绑定

当您想要将多个不同的服务绑定/注册到同一个接口或抽象类时,您需要提供 上下文,否则一个会覆盖另一个。上下文bind 方法的第三个参数,它可以是一个类的字符串表示或映射到类的键,并且该类需要在构造函数或方法中使用接口/抽象类作为类型提示。

// This will result in an override and `Foo\Baz::class` will always be returned for Foo\Bar::interface
$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\BarInterface::class, Foo\Baz::class);

$container->bind(Foo\BarInterface::class, Foo\Bar::class);
$container->bind(Foo\BarInterface::class, Foo\Baz::class, 'FooController');

检索服务

$service = $container['Foo\Bar'];
$service = $container[Foo\Bar::class];
$service = $container['foo'];

// Only works for services mapped to keys
$service = $container->foo();
$service = $container->foo;

// Retrieves a new instance or a singleton if a service has been registered as a singleton
$service = $container->get('foo');

// Always retrieves a singleton
$service = $container->shared('foo');