avris/container
Composer 安装命令:
composer require avris/container
包简介
A dependency injection container with autowiring
README 文档
README
A dependency injection container with autowiring
Installation
composer require avris/container
Usage
Basics
Container resolves dependencies between defined services, in order to simplify the development process, avoid duplication of code, facilitate interoperability and improve maintainability and testability. See: Dependency Injection pattern.
$parameterProvider = new SimpleParameterProvider(['ROOT_DIR' => __DIR__]);
// parameter provider is optional
$container = new Container($parameterProvider);
$container->set('number', 4);
$container->set(Foo::class, new Foo);
$container->setDefinition(Bar::class, [
'arguments' => [
'$foo' => '@' . Foo::class,
'$dir' => '%ROOT_DIR%/bar',
'$number' => '@number',
'$float' => 69.123,
],
'public' => true,
]);
$container->setDefinition(BarInterface::class, Bar::class); // alias
$container->get('number'); // 4
$container->get(Foo::class); // new Foo
$container->get(BarInterface::class); // new Bar(new Foo, __DIR__ . '/bar', 4, 69.123)
$container->getParameter('ROOT_DIR'); // __DIR__
Options
class-- the class of the service, will default to the service name if not given. If the given class implements theResolverinterface, it will be instantiated, and it'sresolvemethod executed to provide an actual value to be put in the container.arguments-- constructor arguments.calls-- method calls to be executed right after constructing the service (setter injection etc.)'calls' => [ ['setLogger', ['@logger']], ['registerListener', ['@listenerA']], ['registerListener', ['@listenerB']], ],tags-- an array of string that help group similar services together; tagged services can be injected with#tagName:$container->setDefinition(HandlerA::class, ['tags' => 'handler']); $container->setDefinition(HandlerB::class, ['tags' => 'handler']); $container->setDefinition(HandlerC::class, ['tags' => 'handler']); $container->setDefinition(Manager::class, ['arguments' => ['$handlers' => '#handler']]);factory-- determines if eachgetshould create a new service (true), or should one service be reused (false, default).resolve-- instead of usingclass+argumentsto construct the service, you can useresolveto define how it should be created:$container->setDefinition('foo', ['resolve' => 4]); // 4 $container->setDefinition('language', ['resolve' => '@Request.locale.language']); // $container->get('Request')->getLocale()->getLanguage()public-- determines if the service should be accessible directly withget, or can it only be injected into other services.
ContainerCompiler: autowiring and autoconfiguration
Usually it's obvious, which service should be injected into another.
For instance when your service has a constructor argument Psr\Cache\CacheItemPoolInterface $cache,
and the container does have a service named Psr\Cache\CacheItemPoolInterface,
then explicitly writing ['arguments' => ['$cache' => '@Psr\Cache\CacheItemPoolInterface'] is redundant.
You can always specify the dependencies manually, then autowiring won't overwrite them.
Autowiring is not magic -- it just follows simple rules to determine, which service should be injected into the constructor:
- if the argument is a class which is defined in the container, use this service,
- if the argument is a class which is not defined in the container, try to autowire that class and create a private service out of it,
- if the argument is an array and its name ends with
s(e.g.array $helpers), inject an array of services with a specific tag (#helper). - if the argument is of type
Bag, inject the config value with its name (e.g.Bag $localisation->@config.localisation), - if its name starts with
env, inject a parameter: (e.g.string $envCacheDir->%CACHE_DIR%) - if none of the above is true, but there is a default value, just use it,
- if none of the above is true, throw an exception -- this argument should be defined explicitly.
Autoconfiguration is another way to make your life simpler.
For instance, if you're using Twig,
you might want all the classes in your code that extend Twig\Extension\AbstractExtension
to be automatically registered as twig extension.
Autoconfiguration lets you define what default config (tags, public etc.) should be added to them.
To use autowiring and autoconfiguration, run the ContainerCompiler:
$container = new Container;
$services = [
'App\' => [
'dir' => '%MODULE_DIR%/src/',
'exclude' => ['#^Entity/#'],
],
'App\Foo' => [
'arguments' => [
'$bar' => 5,
],
],
'App\Bar' => [
'public' => true,
],
];
$autoconfiguration = [
'Twig\Extension\AbstractExtension' => [
'tags' => ['twigExtension'],
],
];
$definitions = new ContainerCompiler(
$container,
$services,
$autoconfiguration
))->compile();
/** @var ServiceDefinition $definition */
foreach ($definitions as $name => $definition) {
if (!$container->has($name)) {
$container->setDefinition($name, $definition);
}
}
In this example, the whole %MODULE_DIR%/src/ except for (the /src/Entity dir) will be scanned for PHP files
and all the found classes will be autowired as private services. If some of them are not used and not public,
they will be removed from the container.
Compiling the container has no impact on performance on production environment,
as long as you cache the result of compile().
ServiceLocator
Service locator restricts access to services in the container only to a selected list of names:
$container = new Container();
$container->set('foo', 'abc');
$container->set('bar', 'def');
$container->set('secret', 'XYZ');
$locator = new ServiceLocator($container, ['foo', 'bar']);
$locator->get('foo'); // 'abc'
$locator->get('bar'); // 'def'
$locator->get('secret'); // Exception
ContainerAssistedBuilder
ContainerAssistedBuilder can be used to join together a couple of ContainerBuilderExtensions
which encapsulate a set of service definitions that form a library together.
For an example, see Avris Localisator.
Micrus
This container was originally built as a part of the Micrus framework.
Copyright
- Author: Andre Prusinowski (Avris.it)
- Licence: MIT
avris/container 适用场景与选型建议
avris/container 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 353 次下载、GitHub Stars 达 0, 最近一次更新时间为 2018 年 01 月 09 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「dependency injection」 「container」 「di」 「Autowiring」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 avris/container 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 avris/container 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 avris/container 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A fast and intuitive dependency injection container.
Dependency injection container for the Monolith framework.
The PSR-11 container bridges
Http Microframework for Hack
PHP Dependency Injection Container
统计信息
- 总下载量: 353
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 5
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-01-09