PHP code example of stefna / di

1. Go to this page and download the library: Download stefna/di 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/ */

    

stefna / di example snippets




use Stefna\DependencyInjection\ContainerBuilder;

$builder = new ContainerBuilder();
$builder->addDefinition([
	ClockInterface::class => fn () => new Clock(),
]);

$container = $builder->build();

$clock = $container->get(ClockInterface::class);



use Stefna\DependencyInjection\Definition\FilterDefinition;
use Stefna\DependencyInjection\Helper\Autowire;

// this will auto-wire all class that ends with Controller
$definition = new FilterDefinition(
	fn (string $className) => str_ends_with('Controller'),
	fn (string $className) => Autowires::cls($className)
);



use Stefna\DependencyInjection\Definition\NamespaceFilterDefinition;

// this will auto-wire all class that are in App\Controller namespace
$controllerDefinitions = NamespaceFilterDefinition::autoWire('App\\Controller\\');
// this will just do a simple new $className() on all classes in App\RequestInput namespace
$requestInputDefinitions = NamespaceFilterDefinition::create('App\\RequestInput\\');




use Stefna\DependencyInjection\ContainerBuilder;

$builder = new ContainerBuilder();
$builder->addContainer($externalContainer);

$container = $builder->build();

$clock = $container->get(ClockInterface::class);



use Stefna\DependencyInjection\ContainerBuilder;
use Stefna\DependencyInjection\Helper\Autowire;

interface A {}

class Obj implements A
{
	public function __construct(public readonly ClockInterface $clock)
	{}
}

$builder = new ContainerBuilder();
$builder->addDefinition([
	ClockInterface::class => fn () => new Clock(),
	Obj::class => Autowire::cls(),
	A::class => Autowire::cls(Obj::class),
]);

$container = $builder->build();

$clock = $container->get(ClockInterface::class);

#[\Attribute(\Attribute::TARGET_PARAMETER)]
final class ConfigValue implements ResolverAttribute
{
	public function __construct(private readonly string $key) {}

	public function resolve(string $type, ContainerInterface $container): mixed
	{
		$config = $container->get(Config::class);
		return $config->get($this->key);
	}
}

final class Test
{
	public function __construct(
		#[ConfigValue('site.config.value')]
		private readonly string $configValue,
	) {}
}

#[\Attribute(\Attribute::TARGET_PARAMETER)]
final class LogChannel implements ConfigureAttribute
{
	public function __construct(private readonly string $channel) {}

	public function configure(object $object, ContainerInterface $container): object
	{
		if ($object instanceof LoggerInterface && class_exists(ChannelWrapper::class)) {
			return new ChannelWrapper($object, $this->channel);
		}
		if ($container->has(LoggerManager::class)) {
			return $container->get(LoggerManager::class)->createLogger($this->channel);
		}
		
		// don't know how to add channel just return the incoming logger
		return $object;
	}
}

final class Test
{
	public function __construct(
		#[LogChannel('test-channel')]
		private readonly LoggerInterface $logger,
	) {}
}



use Stefna\DependencyInjection\Helper\Factory;

class ObjFactory
{
	public function __invoke(ContainerInterface $container)
	{
		return new Obj($container->get(ClockInterface::class));
	}
}

class ComplexFactory
{
	public function __invoke(ContainerInterface $container, string $className)
	{
		if ($className === A::class) {
			return new Obj($container->get(ClockInterface::class));
		}
	}
}

class AutowiredComplexFactory
{
	public function __construct(
		private ClockInterface $clock,
	) {}

	public function __invoke()
	{
		if ($className === B::class) {
			return new Obj($this->clock);
		}
	}
}

$builder->addDefinition([
	ObjFactory::class => fn () => new ObjFactory(),
	Obj::class => Factory::simple(ObjFactory::class),
	ObjFactory::class => fn () => new ComplexFactory(),
	A::class => Factory::full(ComplexFactory::class),
	B::class => Factory::autoWire(AutowiredComplexFactory::class),
]);

use Stefna\DependencyInjection\Helper\Autowire;
use Stefna\DependencyInjection\Helper\Factory;

$builder->addDefinition([
	ComplexFactory::class => Autowire::cls(),
	// or 
	ComplexFactory::class => fn () => new ComplexFactory(new Clock()),
	
	// looks up ComplexFactory from container and if it's not defined crashes
	A::class => Factory::full(ComplexFactory::class),
]);

use Stefna\DependencyInjection\Helper\Autowire;
use Stefna\DependencyInjection\Helper\Factory;

$builder->addDefinition([
	A::class => Factory::autoWire(ComplexFactory::class),
]);