Php 如何不在Laravel控制器方法中使用容器?
我已经开始关注Laravel,我对我的项目中的依赖关系管理有些怀疑。假设我有依赖关系 DependencyA使用DependencyB使用DependencyC: 然后,在我的控制器内: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
<?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');