在L4.2中,对自定义类的依赖注入陷入了不确定循环


Dependency injection on custom classes stuck in indefinite loop in L4.2?

我一直在更改Controllers和helper类以使用依赖项注入,似乎我的helper类陷入了无限循环。

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

这个问题的解决方案是什么我好像犯了什么错误我该怎么做才能在GeneralPerson这样的辅助类上运行测试,同时模拟从它们内部调用的辅助类?

我想一种可行的方法是在我的服务提供商中,执行以下操作:

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) 
    {
    }
}

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

有一些破解的方法可以让它发挥作用:

  • 您可以使用setter注入,在setter方法,而不是在构造函数中当它被实例化时。这有很多缺点,差可测试性是其中最主要的。(请参见http://symfony.com/doc/current/components/dependency_injection/types.html)

  • 在Laravel 5中,您可以使用方法注入,特别是如果依赖关系只与一个或两个方法相关。(请参见http://mattstauffer.co/blog/laravel-5.0-method-injection)

  • 你可以像上面建议的那样做一个存在性检查,或者其他什么带有事件侦听器。但所有这些都掩盖了一个事实。。。

循环依赖关系通常表示设计更改是有序的 ,最好通过重新考虑类之间的交互方式来解决。

  • 如果您的Person和General类完全相互依赖,那么他们有可能分担一项责任合并为一个类。

  • 然而,如果它们依赖于彼此功能的子集,然后可能会有一个单独的类负责躲在那里的某个地方,然后最好的解决方案是将通用功能提取到第三类中。那样的话比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。"