首页 > 解决方案 > Laravel Service Provider - 从方法链中的中间方法获取类实例

问题描述

我想知道您是否可以帮助我解决以下问题。首先,我想告诉你,如果我在这里问这个问题,那是因为我已经尝试了很多选择,但没有一个对我有用。事实证明,我正在使用 Laravel 开发一个包,并且正在使用 Laravel 的依赖注入。但我正处于一个十字路口,我还没有找到出路。我正在尝试从方法链中获取中间方法中的类的实例,让我解释一下。这是与我所拥有的非常相似的代码:

包服务提供者.php

<?php

class PackageServiceProvider extends ServiceProvider
{   
    public function register()
    {
        $this->configureBindings();
    }

    private function configureBindings()
    {
        $this->app->when(A_Class::class)->needs(B_Interface::class)->give(function () {
            return new B_Class();
        });
    }
    ...

A_Class.php

<?php

class A_Class implements A_Interface
{
    private $b_interface;

    public function __construct(B_Interface $b_interface)
    {
        $this->b_interface = $b_interface;
    }

    public function create($arg1, $arg2)
    {
        return $this->b_interface->method_1()->call_another_method_from_another_class();
    }
}

A_Interface.php

<?php

interface A_Interface extends Arrayable, Rendereable
{
        public function create($arg1, $arg2);

        ...
}
<?php

class B_Class implements B_Interface
{
    public function __construct()
    {
        // Here is the question...
        // How could I get here the instance of the class A_Class?
    }

    public function method_1()
    {
        // should return another class instance
    }

    public function method_2()
    {
        // should return another class instance
    }
}

B_Interface.php

<?php

interface B_Interface
{
        public function method_1();

        public function method_2();

        ...
}

如果您从调用该类的位置查看类B_Class``, in the __construct method I'm trying to get the instance of classA_Class```。我尝试了以下方法:

class B_Class implements B_Interface
{
    public function __construct(A_Interface $a_interface)
    {
        // Here is the question...
        // How could I get here the instance of the class A_Class?
    }

但我收到以下错误:

Segmentation fault

我想一定有某种方法可以实现我所需要的。我会提前感谢任何帮助。

标签: phplaravel

解决方案


因为您在 B 类构造函数中引用 A 类,在 A 类构造函数中引用 B 类,所以您引入了循环依赖。

这将解决您遇到的错误,即分段错误,如下所述: https ://laravel.io/forum/11-08-2016-circular-dependency-causes-segmentation-fault-error-when-运行-php-artisan-optimize

所以答案是尽可能去除循环依赖,因为你可以从 A 调用 B 的方法,在运行时调用 A 为无穷大,你会再次得到上面的错误。

如果您的 A 类和 B 类相对较小,我建议在使用循环依赖之前将它们组合起来。

为了兴趣和繁荣,如果您想实现循环依赖,可以通过从 A 的构造函数内部使用单例注册您的 A 类,并使用上面的代码将对不完整对象的引用放入 B 类。我在这里尝试使用 laravel 单例,它未经测试,但希望你能明白。

class A_Class implements A_Interface
{
   public function __construct(B_Interface $b_interface)
   {
      //I dont think you can pass $this to a function when construction is incomplete, hence $that.
      $that = $this;
      App::singleton('A_Class', function($that){
          return $that;
      });
      $this->b_interface = $b_interface;
   }
}

class B_Class implements B_Interface
{
    public function __construct(A_Interface $a_interface)
    {
       //unfinished object, but no more error.
       $this->aClass = App::make('A_Class')
    }
}

推荐阅读