【发布时间】:2019-10-03 23:42:44
【问题描述】:
我已经注册了一个 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.
【问题讨论】:
-
如果您使用 $paypal = app('App\Helpers\PaypalHelper'); 获取类,则在您的控制器中这行得通吗?
-
@mrhn 不,这没有帮助。例如,即使我在帮助程序中手动设置类以返回
Exception类,它仍然返回 PayPal 类。它似乎永远不会回到我的提供程序类中,就好像有某种类型的缓存一样。 -
provides中的类不正确...命名空间.. 最终会是App\Providers\App\Helpers\PayPalHelper -
@lagbox - 不,我不这么认为,我上面有这个声明
use App\Helpers\PaypalHelperInterface; -
除非你给
App起别名,否则它是不正确的......基本上你试图在上面的代码中解析的接口没有任何绑定,它不在提供数组中
标签: laravel containers service-provider