PHP code example of ghostwriter / container

1. Go to this page and download the library: Download ghostwriter/container library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ghostwriter / container example snippets




declare(strict_types=1);

use Ghostwriter\Container\Container;

final readonly class Dependency
{
}

final readonly class Service
{
    public function __construct(
        private Dependency $dependency,
    ) {}

    public function dependency(): Dependency
    {
        return $this->dependency;
    }
}

$container = Container::getInstance();

$service = $container->get(Service::class);

assert($service instanceof Service);
assert($service->dependency() instanceof Dependency);
assert($service === $container->get(Service::class));

$shared = $container->get(Service::class);
$sameShared = $container->get(Service::class);

assert($shared === $sameShared);

$fresh = $container->build(Service::class);

assert($fresh instanceof Service);
assert($fresh !== $shared);

final readonly class Report
{
    public function __construct(
        private string $title,
        private int $pageCount = 1,
    ) {}
}

$report = $container->build(Report::class, [
    'title' => 'Architecture Notes',
    'pageCount' => 42,
]);

$otherReport = $container->build(Report::class, [
    0 => 'Release Notes',
    1 => 5,
]);

use Ghostwriter\Container\Container;

$message = $container->call(
    static function (Dependency $dependency, string $name): string {
        return $name . ' is ready';
    },
    ['name' => 'container']
);

assert($message === 'container is ready');

assert($container->has(Service::class) === true);

interface ClientInterface
{
}

final readonly class RestClient implements ClientInterface
{
}

$container->alias(ClientInterface::class, RestClient::class);

$client = $container->get(ClientInterface::class);

assert($client instanceof RestClient);

interface ClientInterface
{
}

final readonly class RestClient implements ClientInterface
{
}

final readonly class GraphQLClient implements ClientInterface
{
}

final readonly class GitHub
{
    public function __construct(
        private ClientInterface $client,
    ) {}

    public function client(): ClientInterface
    {
        return $this->client;
    }
}

$container->alias(ClientInterface::class, RestClient::class);
$container->bind(GitHub::class, ClientInterface::class, GraphQLClient::class);

$gitHub = $container->get(GitHub::class);

assert($gitHub->client() instanceof GraphQLClient);
assert($container->get(ClientInterface::class) instanceof RestClient);

use Ghostwriter\Container\Interface\ContainerInterface;
use Ghostwriter\Container\Interface\Service\FactoryInterface;

final readonly class Dependency
{
}

final readonly class Service
{
    public function __construct(
        private Dependency $dependency,
    ) {}

    public function dependency(): Dependency
    {
        return $this->dependency;
    }
}

/** @implements FactoryInterface<Service> */
final readonly class ServiceFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container): object
    {
        return new Service($container->get(Dependency::class));
    }
}

$container->factory(Service::class, ServiceFactory::class);

$service = $container->get(Service::class);

assert($service instanceof Service);
assert($service->dependency() instanceof Dependency);

use Ghostwriter\Container\Interface\ContainerInterface;
use Ghostwriter\Container\Interface\Service\ExtensionInterface;

final class GitHubClient
{
    public function __construct(
        private ?string $enterpriseUrl = null,
    ) {}

    public function setEnterpriseUrl(string $enterpriseUrl): void
    {
        $this->enterpriseUrl = $enterpriseUrl;
    }

    public function enterpriseUrl(): ?string
    {
        return $this->enterpriseUrl;
    }
}

/** @implements ExtensionInterface<GitHubClient> */
final readonly class GitHubClientExtension implements ExtensionInterface
{
    public function __invoke(ContainerInterface $container, object $service): void
    {
        $service->setEnterpriseUrl('https://github.example.com');
    }
}

$container->extend(GitHubClient::class, GitHubClientExtension::class);

$client = $container->get(GitHubClient::class);

assert($client->enterpriseUrl() === 'https://github.example.com');

use Ghostwriter\Container\Interface\ContainerInterface;
use Ghostwriter\Container\Interface\BuilderInterface;
use Ghostwriter\Container\Interface\Service\ExtensionInterface;
use Ghostwriter\Container\Interface\Service\FactoryInterface;
use Ghostwriter\Container\Interface\Service\ProviderInterface;

interface TaskInterface
{
}

interface TaskCollectionInterface
{
    public function add(TaskInterface $task): void;

    public function count(): int;
}

final readonly class MainTask implements TaskInterface
{
    public function __construct(
        private string $name,
    ) {}
}

final readonly class FirstTask implements TaskInterface
{
    public function __construct(
        private string $name,
    ) {}
}

final class TaskCollection implements TaskCollectionInterface
{
    /** @var list<TaskInterface> */
    private array $tasks = [];

    public function add(TaskInterface $task): void
    {
        $this->tasks[] = $task;
    }

    public function count(): int
    {
        return count($this->tasks);
    }
}

/** @implements FactoryInterface<TaskCollection> */
final readonly class TaskCollectionFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container): object
    {
        return new TaskCollection();
    }
}

/** @implements ExtensionInterface<TaskCollection> */
final readonly class TaskCollectionExtension implements ExtensionInterface
{
    public function __invoke(ContainerInterface $container, object $service): void
    {
        $service->add(new FirstTask('Task 1'));
        $service->add($container->get(TaskInterface::class));
    }
}

final readonly class TasksProvider implements ProviderInterface
{
    public function boot(ContainerInterface $container): void
    {
        // no-op
    }

    public function register(BuilderInterface $builder): void
    {
        $builder->alias(TaskInterface::class, MainTask::class);
        $builder->alias(TaskCollectionInterface::class, TaskCollection::class);
        $builder->factory(TaskCollection::class, TaskCollectionFactory::class);
        $builder->extend(TaskCollection::class, TaskCollectionExtension::class);
        $builder->set(MainTask::class, new MainTask('Main Task'));
    }
}

$provider = $container->get(TasksProvider::class);
$provider->register($container);
$provider->boot($container);

$tasks = $container->get(TaskCollectionInterface::class);

assert($tasks instanceof TaskCollection);
assert($tasks->count() === 2);

use Ghostwriter\Container\Container;
use Ghostwriter\Container\PsrContainer;

$container = Container::getInstance();
$psrContainer = $container->get(\Psr\Container\ContainerInterface::class);
// or
//$psrContainer = new PsrContainer($container);

assert($psrContainer->has(Service::class) === true);
assert($psrContainer->get(Service::class) instanceof Service);