Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何不在Laravel控制器方法中使用容器?_Php_Laravel_Dependency Injection_Inversion Of Control - Fatal编程技术网

Php 如何不在Laravel控制器方法中使用容器?

Php 如何不在Laravel控制器方法中使用容器?,php,laravel,dependency-injection,inversion-of-control,Php,Laravel,Dependency Injection,Inversion Of Control,我已经开始关注Laravel,我对我的项目中的依赖关系管理有些怀疑。假设我有依赖关系 DependencyA使用DependencyB使用DependencyC: 然后,在我的控制器内: <?php namespace App\Http\Controllers; use App\User; use App\Http\Controllers\Controller; use Some\NamespaceOf\DependencyA; use Illuminate\Container\Con

我已经开始关注Laravel,我对我的项目中的依赖关系管理有些怀疑。假设我有依赖关系 DependencyA使用DependencyB使用DependencyC:

然后,在我的控制器内:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;
use Some\NamespaceOf\DependencyA;
use Illuminate\Container\Container;

class SomeController extends Controller
{
    // ...

    /**
     * @param DependencyA  $a
     * @return Response
     */
    public function controllerMethod(DependencyA $a, Container $container)
    {
        $container->call([$a, 'someMethod']);
        // ...
    }

    // ...
}
我不喜欢在我的组件之间反复传递控制器

在这种情况下,什么是最好的重构?将控制器重写为:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;
use Some\NamespaceOf\DependencyA;
use Some\NamespaceOf\DependencyB;
use Illuminate\Container\Container;

class SomeController extends Controller
{
    // ...

    /**
     * @param DependencyA  $a
     * @return Response
     */
    public function controllerMethod(DependencyA $a, DependencyB $b)
    {
        $a->someMethod($b);
        // ...
    }

    // ...
}
这还不够,因为DependencyA还需要容器在调用$b->doSomething传递$c之前查找DependencyC。我也必须编辑DependencyA,但是我怎样才能向它注入DependencyC呢

当这些依赖关系形成时,应该怎么做? 在组件中使用容器使我认为违反了IoC原则


谢谢你的关注。

如果我理解你的意思;这可能会有帮助:

AppServiceProvider:

从属关系a:

从属关系b:

从属关系c:

现在,在我们的控制器中,如果我们使用DependencyA作为唯一的依赖项;DependencyA类和DependencyB类的依赖关系将分别得到解决

财务主任:

<?php

namespace App\Http\Controllers;

use App\User;
use App\Http\Controllers\Controller;
use Some\NamespaceOf\DependencyA;
use Illuminate\Container\Container;

class SomeController extends Controller
{
    // ...

    /**
     * @param DependencyA  $a
     * @return Response
     */
    public function controllerMethod(DependencyA $a, Container $container)
    {
        $container->call([$a, 'someMethod']);
        // ...
    }

    // ...
}
web.php


现在,如果您访问,例如。http://127.0.0.1:8000/dependant 你会看到我的。作为此实现的结果。

尽量不要将依赖项作为参数发送。我认为这是唯一的方法,不是吗。但是我觉得我失去了语义,但也许这只是一个错误的结论,我不需要关注它…所以基本上规则不是创建带有类型提示参数的方法,而是类型提示构造函数。。。对吧?这不是关于你在哪里输入提示。如果您提供DepA作为索引操作的参数,则Laravel的行为将与此相同。但依赖关系的上下文将仅限于索引。这甚至可能会根据您的结构提高应用程序性能。我解决上述问题的方法称为自动注入。但是,如果需要更改对运行时的依赖关系,并且条件绑定不是解决方案;传递手动解析的依赖项可能是一种选择。让我们把这个解决方案称为一个好的实践。你知道,没有银弹。
namespace App\Providers;

use App\Dependencies\DependencyA;
use App\Dependencies\DependencyB;
use App\Dependencies\DependencyC;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(DependencyB::class, function ($app) {
            return new DependencyB(new DependencyC());
        });

        $this->app->bind(DependencyA::class, function ($app) {
            return new DependencyA($app->make(DependencyB::class));
        });
    }
}
namespace App\Dependencies;

class DependencyA
{
    private $dependencyB;

    public function __construct(DependencyB $dependencyB)
    {
        $this->dependencyB = $dependencyB;
    }

    public function useMe()
    {
        return $this->dependencyB->useMe();
    }
}
namespace App\Dependencies;

class DependencyB
{
    private $dependencyC;

    public function __construct(DependencyC $dependencyC)
    {
        $this->dependencyC = $dependencyC;
    }

    public function useMe()
    {
        return $this->dependencyC->useMe();
    }
}
namespace App\Dependencies;

class DependencyC
{
    public function useMe()
    {
        echo "Used me.";
    }
}
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Dependencies\DependencyA;

class DependantController extends Controller
{
    private $dependencyA;

    public function __construct(DependencyA $dependencyA)
    {
        $this->dependencyA = $dependencyA;
    }

    public function index()
    {
        $this->dependencyA->useMe();
    }
}
Route::get('dependant', 'DependantController@index');