Attributes
Container can resolve attributes as decorator, by default, there has some basic attributes you can use.
[Autowire]
For example, if you create a class with dependencies which has not set to container, you will get error.
class Flower
{
public function __construct(public Sakura $sakura)
{}
}
$container->newInstance(Flower::class); // Error
But we can use #[Autowire]
to auto create dependent objects, you must manually register this attribute first.
use Windwalker\Attributes\AttributeType;
use Windwalker\DI\Attributes\Autowire;
// Register it
$container->getAttributesResolver()
->registerAttribute(Autowire::class, AttributeType::PARAMETERS);
class Flower
{
public function __construct(#[Autowire] public Sakura $sakura)
{}
}
$flower = $container->newInstance(Flower::class); // No error
$flower->sakura; // Sakura object
It will always create new object everytime:
$flower1 = $container->newInstance(Flower::class);
$flower2 = $container->newInstance(Flower::class);
$flower1->sakura !== $flower2->sakura;
More about using attribute decorators, please see Attributes Document
[Inject]
#[Inject]
is an attribute to make Container inject object to a property. The class which you want to inject, should
be set into Container before you inject it.
use Windwalker\Attributes\AttributeType;
use Windwalker\DI\Attributes\Inject;
// Register attribute.
$container->getAttributesResolver()
->registerAttribute(Inject::class, AttributeType::PROPERTIES | AttributeType::PARAMETERS);
// Prepare it.
$container->prepareSharedObject(Sakura::class);
class Flower
{
#[Inject]
protected Sakura $sakura;
public function __construct()
{}
}
$flower = $container->newInstance(Flower::class);
$flower->sakura; // Sakura object
#[Inject]
can also use on parameters:
public function __construct(#[Inject] public Sakura $sakura)
{}
Or directly set a class name:
#[Inject(Sakura::class)]
protected FlowerInterface $flower;
[Service]
#[Service]
is similar to `#[Autowire], it will create a new object if class haven't set into Container.
But after first created it, then it will always get same object.
use Windwalker\Attributes\AttributeType;
use Windwalker\DI\Attributes\Service;
// Register attribute.
$container->getAttributesResolver()
->registerAttribute(Service::class, AttributeType::PARAMETERS);
class Flower
{
public function __construct(#[Service] public Sakura $sakura)
{}
}
$flower1 = $container->newInstance(Flower::class);
$flower2 = $container->newInstance(Flower::class);
// Same
$flower1->sakura === $flower2->sakura;
You can also direct a class name:
public function __construct(#[Service(Foo::class)] public FooInterface $foo)
{}
Register new Attributes
use Windwalker\DI\Attributes\AttributeType;
$resolver = $container->getAttributesResolver();
$resolver->registerAttribute(MyAttribute::class, AttributeType::CLASSES);