laravel - 如何在 laravel 容器中交换依赖项
问题描述
我已经注册了一个 Paypal 服务提供商:
App\Providers\PaypalHelperServiceProvider::class,
并且,当我在控制器中输入提示时,它会正确解析:
public function refund(Request $request, PaypalHelper $paypal) {...
这是我的提供者类:
class PaypalHelperServiceProvider extends ServiceProvider
{
protected $defer = true;
public function register()
{
$this->app->bind('App\Helpers\PaypalHelper', function() {
$test = 'test';
return new PaypalHelper();
});
}
public function provides()
{
$test = 'test';
return [App\Helpers\PaypalHelper::class];
}
}
一切都按预期工作。现在我希望能够修改控制器以采用 PayPal 接口。然后,我将更新我的服务提供者,以有条件地传入真实类或模拟类进行测试,使用 APP_ENV 变量来确定使用哪一个。我将一些调试器放入服务提供者类中,但无法让它进入。我认为它可能只在需要时加载它们,所以我在控制器中放置了一个断点。该类确实解决了,但它仍然从未进入服务提供者类!有人可以向我解释为什么会这样吗?即使我修改了代码以传入不同的类类型,它也没有被接受。
编辑:
这是我调试时看到的代码流:ControllerDispatcher -> resolveClassMethodDependencies -> resolveMethodDependencies -> transformDependency。此时我们在 RouteDependencyResolveerTrait 中有如下 laravel 代码:
protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters)
{
$class = $parameter->getClass();
// If the parameter has a type-hinted class, we will check to see if it is already in
// the list of parameters. If it is we will just skip it as it is probably a model
// binding and we do not want to mess with those; otherwise, we resolve it here.
if ($class && ! $this->alreadyInParameters($class->name, $parameters)) {
return $this->container->make($class->name);
}
}
由于 getClass() 总是解析为接口名称,所以当我们调用 container->make() 时,它总是会失败
Target [App\Helpers\PaypalHelperInterface] is not instantiable.
解决方案
改变
$this->app->bind('App\Helpers\PaypalHelper', function() {
$test = 'test';
return new PaypalHelper();
});
至
if (app()->environment('testing')) {
$this->app->bind(
PaypalHelperInterface::class,
FakePaypalHelper::class
)
} else {
$this->app->bind(
PaypalHelperInterface::class,
PaypalHelper::class
);
}
推荐阅读
- mysql - Spring Boot 微服务的 MySQL 配置
- html - 使两个 div 在大屏幕上并排响应,在移动设备上彼此下方
- c# - 如何计算带有变量的按钮的名称
- typescript - 在 TypeScript 中,如果内联函数采用泛型类型的参数,我如何从中“获取”类型参数?
- modelica - 无法求解线性方程组
- c# - 我怎样才能只编码一次并复制 c#
- reactjs - ReactJs - ReferenceError:未定义提取
- java - 作业因阶段失败而中止:阶段 5.0 中的任务 0 失败 1 次,最近一次失败:阶段 5.0 中的任务 0.0 丢失
- excel - 列中唯一值的高级过滤器复制重复值
- php - 上传规则不会覆盖 IC