PHP特征中的依赖注入

时间:2016-08-10 15:26:59

标签: php magento dependency-injection traits magento2

特征是否真的适用于依赖注入?请考虑以下代码:

特质班

namespace Frame\Slick\Block;
use Frame\Slider\Slick\Block\Data as Helper

trait Slick
{
   protected $_slickHelper;
   public function __construct(Helper $slickHelper) 
   {
     $this->_slickHelper = $slickHelper;
   }
}

使用特征的类

namespace Frame\Slick\Block;

class Product ListProduct implements BlockInterface 
{
   use Slick;
   public function testTrait()
   {
      return $this->_slickHelper->getHelloWorld();
   }
}

这似乎总是返回null,我非常确定所有内容都被正确包含在内。特质能真正支持依赖注入吗?

3 个答案:

答案 0 :(得分:3)

是的,他们工作特质的代码被“粘贴”在赞美级别。请考虑以下代码。它按预期工作,并回声适当的价值。你的问题在别处。

<?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();

代码将回显'test'。 Working fiddle

答案 1 :(得分:1)

正确实现的框架应该能够对特征构造函数进行依赖注入。通常,使用反射确定适合注射的参数。请考虑以下示例:

<?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());

打印:

ReflectionClass Object
(
    [name] => D
)

这表明框架可以使用反射来确定是否注入依赖项,构造函数在特征中的事实并不重要。

如果在magento中没有发生这种情况,那么我建议你将其移到他们的建议主题(如果有的话)。

我还建议您通过dependency injection documentation

了解依赖注入如何在magento中工作

答案 2 :(得分:0)

不要使用构造函数!

/*
This method can be used to download an image from the internet using a url in Android. This use Android Download Manager to
download the file and added it to the Gallery. Downloaded image will be saved to "Pictures"
Folder in your internal storage
*/

private void downloadImageNew(String filename, String downloadUrlOfImage){
    try{
        DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
        Uri downloadUri = Uri.parse(downloadUrlOfImage);
        DownloadManager.Request request = new DownloadManager.Request(downloadUri);
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle(filename)
                .setMimeType("image/jpeg") // Your file type. You can use this code to download other file types also.
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                .setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES,File.separator + filename + ".jpg");
        dm.enqueue(request);
        Toast.makeText(this, "Image download started.", Toast.LENGTH_SHORT).show();
    }catch (Exception e){
        Toast.makeText(this, "Image download failed.", Toast.LENGTH_SHORT).show();
    }
}