【问题标题】:Dependency injection on custom classes stuck in indefinite loop in L4.2?自定义类的依赖注入在 L4.2 中陷入无限循环?
【发布时间】:2014-12-17 06:03:46
【问题描述】:

我一直在更改我的控制器和辅助类以使用依赖注入,似乎我的辅助类陷入了无限循环。

下面是我的自定义 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) 
    {
    }
}

【问题讨论】:

  • 你认为代码缩进正确吗?
  • @hek2mgl 您指的是代码在问题中的显示方式吗?在我看来没问题...如果您有可读性建议,请提交编辑
  • @John 这不好。一点都不好。你需要重构你的类。避免循环依赖。
  • @John 请提供场景为什么需要循环依赖。这将了解问题的核心并得出解决方案!
  • @brainless 我不需要循环依赖 :) 我意识到这就是我要在这里结束的,所以问题是如何从这种情况中删除循环依赖。

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


【解决方案1】:

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

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

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

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

  • 但是,如果它们依赖于彼此功能的子集, 那么可能有一个单独的类有自己的责任 躲在某个地方,然后最好的解决方案是 将通用功能提取到第三类。这样一来,反而 比让 A 类依赖 B 类和 B 类依赖 A 类,两者都 A 类和 B 类将依赖于 C 类。您可以安全地 将它们全部实例化,它们都可以轻松测试。

您如何轻松确定您的新 C 类应包含哪些内容?一个很好的经验法则来自http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/...“列出你的A类中被B类使用的所有方法,以及你的B类中被A类使用的所有方法。两个列表中较短的是你的隐藏C类。”

【讨论】:

    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2013-03-17
    相关资源
    最近更新 更多