加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 自定义类的依赖注入在L4.2中陷入无限循环?

发布时间:2020-12-13 16:32:55 所属栏目:PHP教程 来源:网络整理
导读:我一直在改变我的控制器和辅助类以使用依赖注入,似乎我的助手类被卡在无限循环中. 下面是我的自定义ServiceProvider和两个示例助手类.正如你所看到的,他们互相注入,所以他们不停地来回走动. 这个问题的解决方案是什么?我似乎犯了什么错误?我可以做什么,以
我一直在改变我的控制器和辅助类以使用依赖注入,似乎我的助手类被卡在无限循环中.

下面是我的自定义ServiceProvider和两个示例助手类.正如你所看到的,他们互相注入,所以他们不停地来回走动.

这个问题的解决方案是什么?我似乎犯了什么错误?我可以做什么,以便我可以对辅助类(如General和Person)运行测试,同时模拟从它们内部调用的辅助类?

我认为可行的一种方法是在我的ServiceProvider中,执行以下操作:

if (isset($appmade->General)) { 
    // inject the General app that's already instantiated 
} else { 
    $abc = app::make('LibMyOrgGeneral'); 
    $appmade->General = $abc; 
}

这是正确的方法吗?

// /app/providers/myorg/MyOrgServiceProvider.php

namespace MyOrgServiceProvider;
use IlluminateSupportServiceProvider;
class MyOrgServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('LibMyOrgGeneral',function ($app) {
            return new LibMyOrgGeneral(
                $app->make('LibMyOrgPerson'),$app->make('AppModelsUser')
            );
        });

        $this->app->bind('LibMyOrgPerson',function ($app) {
            return new LibMyOrgPerson(
                $app->make('LibMyOrgGeneral'),$app->make('AppModelsDevice')
            );
        });
    }
}

// /app/libraries/myorg/general.php

namespace LibMyOrg;
use AppModelsUser;
use LibMyOrgPerson;
class General
{
    protected $model;
    protected $class;

    public function __construct(Person $personclass,User $user) 
    {
    }
}

// /app/libraries/myorg/person.php

namespace LibMyOrg;
use AppModelsDevice;
use LibMyOrgGeneral;
class Person
{
    protected $model;
    protected $class;

    public function __construct(General $generalclass,Device $device) 
    {
    }
}
你的助手类有一个循环依赖的情况,当与依赖注入混合时,使它们不可实例化……并且没有好的方法让它们工作并且易于测试.

有一些hack-y方法可以让它工作:

>你可以使用setter注入,在a中注入依赖项
使用helper时的setter方法,而不是构造函数中的setter方法
当它被实例化时.这有很多缺点,很差
可测试性是其中的主要部分. (看到
http://symfony.com/doc/current/components/dependency_injection/types.html)
>在Laravel 5中,你可以使用方法注入,特别是如果
依赖性仅与一种或两种方法相关. (看到
http://mattstauffer.co/blog/laravel-5.0-method-injection)
>你可以像上面提到的那样进行存在检查,或者其他什么
与事件监听器.但所有这一切都掩盖了……

循环依赖通常表示设计更改是有序的,最好通过重新考虑类如何相互交互来解决.

>如果您的人员和普通班级完全相互依赖,那么
他们可能共同承担一项责任,应该是
合并成一个单一的课程.
>但是,如果他们依赖于彼此功能的子集,
然后可能有一个单独的班级,有自己的责任
隐藏在某处,然后是最好的解决方案
将常用功能提取到第3类.那样的话
比A类依赖B类而B类依赖A类
A类和B类将依赖于C类.您可以安全地使用
将它们全部实例化,它们都很容易测试.

你怎么能容易地弄清楚你的新C类应该包含什么?一个很好的经验法则来自http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/ ……“列出类B使用的类A中的所有方法,以及类A使用的类B中的所有方法.两个列表中较短的一个是隐藏的C类“.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读