Do traits actually work with dependency injection? Consider the following code:
Trait Class
namespace Frame\Slick\Block;
use Frame\Slider\Slick\Block\Data as Helper
trait Slick
{
protected $_slickHelper;
public function __construct(Helper $slickHelper)
{
$this->_slickHelper = $slickHelper;
}
}
Class using the trait
namespace Frame\Slick\Block;
class Product ListProduct implements BlockInterface
{
use Slick;
public function testTrait()
{
return $this->_slickHelper->getHelloWorld();
}
}
This seems to always return null, am very sure everything is being included properly. Can trait really support dependency injection?
Dependency injection is a procedure where one object supplies the dependencies of another object. Dependency Injection is a software design approach that allows avoiding hard-coding dependencies and makes it possible to change the dependencies both at runtime and compile time.
Traits are used to declare methods that can be used in multiple classes. Traits can have methods and abstract methods that can be used in multiple classes, and the methods can have any access modifier (public, private, or protected).
This provides a developer with the freedom to create a computer object with different components without having to extend classes and override constructors.
Unlike traits in Scala, traits in PHP can have a constructor but it must be declared public (an error will be thrown if is private or protected). Anyway, be cautious when using constructors in traits, though, because it may lead to unintended collisions in the composing classes.
Yes they work the code from trait is "pasted" on compliation level. Consider the following code. It works as expected and echos proper value. Your problem is elsewhere.
<?php
class Dependency
{
public function foo()
{
return 'test';
}
}
trait Slick
{
protected $dep;
public function __construct(Dependency $dep)
{
$this->dep = $dep;
}
}
class Product
{
use Slick;
public function testTrait()
{
return $this->dep->foo();
}
}
echo (new Product(new Dependency()))->testTrait();
The code will echo 'test'. Working fiddle
A properly implemented framework should be able to do dependency injection on trait constructors. Typically parameters which are eligible for injection are determined using reflection. Consider the following example:
<?php
class D {}
trait T {
public function __construct(D $d) { }
}
class A {
use T;
}
$cls = new ReflectionClass("A");
$ctor = $cls->getConstructor();
print_r($ctor->getParameters()[0]->getClass());
Prints:
ReflectionClass Object
(
[name] => D
)
This indicates that the framework can use reflection to determine whether or not to inject the dependency, the fact that the constructor is in the trait does not matter.
If this is not happening in magento then I suggest you move this to their suggestion thread (if any).
I would also recommend you read up on how dependency injection works in magento via their dependency injection documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With