【问题标题】:Is this the right way to use dependency injection with the Service Container?这是对服务容器使用依赖注入的正确方法吗?
【发布时间】:2017-11-21 16:22:51
【问题描述】:

所以,我有两个不同的课程:

A 类

class A implements SomeContract
{
    public function extraThicc()
    {
        return 'Filthy Frank';
    } 
}

B 类

class B implements SomeContract
{
    public function extraThicc()
    {
        return 'iDubbbz';
    } 
}

界面

interface SomeContract
{
    public function extraThicc();
}

老板班

class Boss
{
    public $someVar

    public function __construct(SomeContract $someVar)
    {
        $this->someVar = $someVar;
    }
}

服务提供商

    $this->app->bind('Boss::class', function($app,$param){
        if ($param['type'] == 'A') return new A();
        if ($param['type'] == 'B') return new B();
    });

解决办法

public function boss($type)
{
    return app()->makeWith('Boss::class', ['type'=>$type')]);
}

门面

class CoolFacade extends Facade
{
    protected static function getFacadeAccessor() { return 'cool'; }
}

控制者

class StarWarsBattlefrontController extends Controller
{
    public function index()
    {
        return 'Star Wars: Battlefront 2 Loot Boxes are bad, says:'.Cool::Boss('A')->extraThicc();
    }
}

有没有更好的方法将依赖项注入到类中?因为我认为这不是在服务提供者的绑定方法中使用 if 语句的好习惯。

【问题讨论】:

    标签: php laravel dependency-injection


    【解决方案1】:

    嗯,你的方法不是真正的依赖注入,而是 Facades。如果您阅读Laravel Docs on Facades,您会发现他们只是将它们描述为简单的访问器,但不应滥用它们。相反,必须注入依赖项。

    对于您需要的内容,您可能想在Contextual Binding 上阅读,类似于

    $this->app->when(BossA::class)
              ->needs(SomeContract::class)
              ->give(function () {
                  return new A;
              });
    
    $this->app->when(BossB::class)
              ->needs(SomeContract::class)
              ->give(function () {
                  return new B;
              });
    

    【讨论】:

    • 我的问题是,我使用了 3 个不同的类:GoogleMaps、OSRM、MapBox。它们共享相同的函数名称(方法很相似)。有没有一种方法,可以在什么时候返回一个类需要吗?
    • 不确定您要完成什么。也许更新您的问题会有所帮助(?)。
    • $this->app->bind('\App\Acme\GeoServices\Geo::class', function($app,$param){ if ($param['type'] == 'Google') return new GoogleMaps($param); if ($param['type'] == 'Mapbox') return new Mapbox($param); if ($param['type'] == 'OSRM') return new OpenStreetMaps($param); }); 这样的东西,所以当我需要 OSRM 类时,我会返回 Flow::GIS('OSRM')->routes('ARAD.AL-ARYAN.KEFAR GALLIM.KEFAR SHEMARYAHU.NEWE UR.REKHASIM')->distance();
    • 同样,您用于调用实现对象的模式不是依赖注入。那是一个门面。我将您链接到文档,以便您阅读它。对于一个实例的多个实现,请阅读我已经链接的上下文绑定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    相关资源
    最近更新 更多