<?php

declare(strict_types=1);

namespace App\Framework\DI;

use App\Framework\Core\ValueObjects\ClassName;
use Stringable;

interface Container
{
    public MethodInvoker $invoker {get;}

    public ContainerIntrospector $introspector {get;}

    /**
     * @template T of object
     * @param class-string<T>|ClassName $class
     * @return T
     */
    public function get(ClassName|Stringable|string $class): object;

    /** @param class-string $class */
    public function has(ClassName|Stringable|string $class): bool;

    public function bind(
        ClassName|Stringable|string $abstract,
        callable|string|object $concrete
    ): void;

    public function singleton(
        ClassName|Stringable|string $abstract,
        callable|string|object $concrete
    ): void;

    public function instance(
        ClassName|Stringable|string $abstract,
        object $instance
    ): void;

    /** @param class-string $class */
    public function forget(ClassName|Stringable|string $class): void;
}
