Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.
/ container Public archive
generated from spaceonfire/skeleton

Commit

Permalink
Merge pull request #5 from spaceonfire/rename-chain-to-composite
Browse files Browse the repository at this point in the history
Rename chain to composite
  • Loading branch information
tntrex authored Oct 22, 2020
2 parents 589c0d5 + bea5360 commit 9340688
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 226 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
pull_request:
branches:
- master
workflow_dispatch:

jobs:
composer:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
- Nothing
-->

## [2.2.0] - 2020-10-22
### Deprecated
- Class `spaceonfire\Container\ContainerChain` renamed to `spaceonfire\Container\CompositeContainer`.
This name clearly describes what this class does and just fits best.
Class alias provided for backwards compatibility, but will be removed in next major release.

## [2.1.1] - 2020-09-26
### Fixed
- Development config updates
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ $ composer require spaceonfire/container
```php
use spaceonfire\Container\Container;
use spaceonfire\Container\ReflectionContainer;
use spaceonfire\Container\ContainerChain;
use spaceonfire\Container\CompositeContainer;

$container = new ContainerChain([
$container = new CompositeContainer([
new Container(),
new ReflectionContainer(),
]);
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
"dev-master": "2.2-dev"
}
},
"config": {
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ parameters:
- '/expects callable(.*) array(.*) given\.$/'
- '/no value type specified in iterable type(.*)spaceonfire\\Container\\Definition\\DefinitionAggregate/'
- '/no value type specified in iterable type(.*)spaceonfire\\Container\\ServiceProvider\\ServiceProviderAggregate/'
-
message: '/^If condition is always false\.$/'
paths:
- src/ContainerChain.php
3 changes: 3 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
<exclude>
<file>src/ContainerChain.php</file>
</exclude>
</whitelist>
</filter>
<logging>
Expand Down
231 changes: 231 additions & 0 deletions src/CompositeContainer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
<?php

declare(strict_types=1);

namespace spaceonfire\Container;

use Psr\Container\ContainerInterface as PsrContainerInterface;
use spaceonfire\Collection\Collection;
use spaceonfire\Collection\CollectionInterface;
use spaceonfire\Container\Definition\DefinitionInterface;
use spaceonfire\Container\Exception\ContainerException;
use spaceonfire\Container\Exception\NotFoundException;

/**
* Class CompositeContainer
*
* Attention: You should not extend this class because it will become final in the next major release
* after the backward compatibility aliases are removed.
*
* @package spaceonfire\Container
* @final
*/
class CompositeContainer implements ContainerWithServiceProvidersInterface, ContainerAwareInterface
{
use ContainerAwareTrait;

/**
* @var PsrContainerInterface[]
*/
private $containers = [];
/**
* @var ContainerInterface|null
*/
private $primary;

/**
* CompositeContainer constructor.
* @param PsrContainerInterface[] $containers
*/
public function __construct(iterable $containers)
{
$this->setContainer($this);
$this->addContainers($containers);
}

/**
* @inheritDoc
*/
public function setContainer(ContainerInterface $container): ContainerAwareInterface
{
$this->container = $container;
foreach ($this->containers as $delegate) {
if ($delegate instanceof ContainerAwareInterface) {
$delegate->setContainer($container);
}
}
return $this;
}


/**
* Getter for `primary` property
* @return ContainerInterface
*/
private function getPrimary(): ContainerInterface
{
if ($this->primary === null) {
throw new ContainerException('No primary container provided with support of definitions');
}

return $this->primary;
}

/**
* Setter for `primary` property
* @param ContainerInterface $primary
*/
private function setPrimary(ContainerInterface $primary): void
{
if (
$this->primary === null ||
(
!$this->primary instanceof ContainerWithServiceProvidersInterface &&
$primary instanceof ContainerWithServiceProvidersInterface
)
) {
$this->primary = $primary;
}
}

/**
* Add containers to the chain
* @param PsrContainerInterface[] $containers
* @return $this
*/
public function addContainers(iterable $containers): self
{
foreach ($containers as $container) {
$this->addContainer($container);
}
return $this;
}

/**
* Add container to the chain
* @param PsrContainerInterface $container
* @return $this
*/
public function addContainer(PsrContainerInterface $container): self
{
if ($container instanceof ContainerInterface) {
$this->setPrimary($container);
}

if ($container instanceof ContainerAwareInterface) {
$container->setContainer($this->getContainer());
}

$this->containers[] = $container;
return $this;
}

/**
* @inheritDoc
*/
public function get($id, array $arguments = [])
{
foreach ($this->containers as $container) {
if ($container->has($id)) {
return $container instanceof ContainerInterface
? $container->get($id, $arguments)
: $container->get($id);
}
}

throw new NotFoundException(sprintf('Alias (%s) is not being managed by any container in chain', $id));
}

/**
* @inheritDoc
*/
public function has($id): bool
{
foreach ($this->containers as $container) {
if ($container->has($id)) {
return true;
}
}

return false;
}

/**
* @inheritDoc
*/
public function make(string $alias, array $arguments = [])
{
return $this->getPrimary()->make($alias, $arguments);
}

/**
* @inheritDoc
*/
public function invoke(callable $callable, array $arguments = [])
{
return $this->getPrimary()->invoke($callable, $arguments);
}

/**
* @inheritDoc
*/
public function add(string $id, $concrete = null, bool $shared = false): DefinitionInterface
{
return $this->getPrimary()->add($id, $concrete, $shared);
}

/**
* @inheritDoc
*/
public function share(string $id, $concrete = null): DefinitionInterface
{
return $this->getPrimary()->share($id, $concrete);
}

/**
* @inheritDoc
*/
public function addServiceProvider($provider): ContainerWithServiceProvidersInterface
{
$primary = $this->getPrimary();

if ($primary instanceof ContainerWithServiceProvidersInterface) {
$primary->addServiceProvider($provider);
return $this;
}

throw new ContainerException('No container provided with support of service providers');
}

/**
* @inheritDoc
*/
public function hasTagged(string $tag): bool
{
foreach ($this->containers as $container) {
if ($container instanceof ContainerInterface && $container->hasTagged($tag)) {
return true;
}
}

return false;
}

/**
* @inheritDoc
*/
public function getTagged(string $tag): CollectionInterface
{
$result = new Collection();

foreach ($this->containers as $container) {
if (!$container instanceof ContainerInterface) {
continue;
}

$result = $result->merge($container->getTagged($tag));
}

return $result;
}
}
Loading

0 comments on commit 9340688

Please sign in to comment.