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

时间:2014-10-21 21:13:03

标签: php unit-testing laravel laravel-4 phpunit

我一直在更改我的控制器和帮助器类以使用依赖注入,似乎我的助手类被卡在无限循环中。

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

这个问题的解决方案是什么? 我似乎犯了什么错误?我可以做什么,以便我可以在GeneralPerson等辅助类上运行测试,同时模拟调用的辅助类从他们里面?

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

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

这是正确的方法吗?

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

namespace MyOrg\ServiceProvider;
use Illuminate\Support\ServiceProvider;
class MyOrgServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('\Lib\MyOrg\General', function ($app) {
            return new \Lib\MyOrg\General(
                $app->make('\Lib\MyOrg\Person'),
                $app->make('\App\Models\User')
            );
        });

        $this->app->bind('\Lib\MyOrg\Person', function ($app) {
            return new \Lib\MyOrg\Person(
                $app->make('\Lib\MyOrg\General'),
                $app->make('\App\Models\Device')
            );
        });
    }
}

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

namespace Lib\MyOrg;
use App\Models\User;
use Lib\MyOrg\Person;
class General
{
    protected $model;
    protected $class;

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

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

namespace Lib\MyOrg;
use App\Models\Device;
use Lib\MyOrg\General;
class Person
{
    protected $model;
    protected $class;

    public function __construct(General $generalclass, Device $device) 
    {
    }
}

1 个答案:

答案 0 :(得分:12)

你的助手类有一个循环依赖的情况,当与依赖注入混合时,使它们不可实例化......并且没有好的方法让它们工作很容易测试。

有一些黑客方法可以让它发挥作用:

循环依赖关系通常表示设计更改 ,最好通过重新考虑您的类如何相互交互来解决。

  • 如果您的人员和普通班级完全相互依赖,那么 他们可能共同承担一项责任,应该是 合并成一个班级。

  • 但是,如果他们依赖彼此的功能, 然后可能是一个独立的班级,有自己的责任 隐藏在某处,然后是最好的解决方案 将常用功能提取到第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类。"