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


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); // true
assert($service->dependency() instanceof Dependency); // true

use Ghostwriter\Container\Attribute\Inject;

final readonly class Service
{
    public function __construct(
        #[Inject(Dependency::class)]
        private DependencyInterface $dependency
    ) {}

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

// the above is equivalent to the following
// $container->alias(Dependency::class, DependencyInterface::class);

final readonly class Service
{
    public function __construct(
        #[Inject(Dependency::class, Service::class)]
        private DependencyInterface $dependency
    ) {}

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

// the above is equivalent to the following
// $container->bind(Service::class, DependencyInterface::class, Dependency::class);

use Ghostwriter\Container\Attribute\Factory;

#[Factory(ServiceFactory::class)]
final readonly class Service
{
    public function __construct(
        #[Factory(DependencyFactory::class)]
        private Dependency $dependency
    ) {}

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

// the above is equivalent to the following
// $container->factory(Dependency::class, DependencyFactory::class);
// $container->factory(Service::class, ServiceFactory::class);

use Ghostwriter\Container\Attribute\Extension;

#[Extension(ServiceExtension::class)]
final readonly class Service
{
    public function __construct(
        #[Extension(DependencyExtension::class)]
        private Dependency $dependency
    ) {}

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

// the above is equivalent to the following
// $container->extend(Service::class, ServiceExtension::class);
// $container->extend(Dependency::class, DependencyExtension::class);

interface TaskInterface {}

final readonly class Task implements TaskInterface {}

final class Tasks
{
    private array $tasks = [];
    public function addTask(TaskInterface $task)
    {
        $this->tasks[] = $task;
    }
}

final readonly class TasksServiceProvider implements ServiceProviderInterface
{
    public function __invoke(ContainerInterface $container)
    {
        $container->alias(TaskInterface::class, Task::class);

        $container->set(Tasks::class, static function (Container $container) {
            /** @var Tasks $tasks */
            $tasks = $container->build(Tasks::class);

            foreach ($container->tagged(Task::class) as $service) {
                $tasks->addTask($service);
            }

            return $tasks;
        }, [Tasks::class, 'tasks']);
    }
}

$container->provide(TasksServiceProvider::class);

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

assert($service instanceof Task); // true

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 getClient(): ClientInterface
    {
        return $this->client;
    }
}

// When GitHub::class asks for ClientInterface::class, it would receive an instance of GraphQLClient::class.
$container->bind(GitHub::class, ClientInterface::class, GraphQLClient::class);

// When any other service asks for ClientInterface::class, it would receive an instance of RestClient::class.
$container->alias(ClientInterface::class, RestClient::class);

/**
 * @implements ExtensionInterface<GitHubClient>
 */
final readonly class GitHubExtension implements ExtensionInterface
{
    /**
     * @param GitHubClient $service
     * @return GitHubClient
     */
    public function __invoke(ContainerInterface $container, object $service): object
    {
        $service->setEnterpriseUrl(
            $container->get(GitHubClient::GITHUB_HOST)
        );

        return $service;
    }
}

$container->alias(GitHubClientInterface::class, GitHubClient::class);
$container->extend(GitHubClientInterface::class, $container->get(GitHubExtention::class));

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

    public function dependency():Dependency
    {
        return $this->dependency;
    }
}
final readonly class ServiceFactory {
  public function __invoke(Container $container): Service
  {
     return new Service($container->get(Dependency::class));
  }
}

$container = Container::getInstance();

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

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

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