我正在使用Laravel Framework 5.8.21
。我正在尝试将interface
绑定到基于Request
的{{1}}方法中的AppServiceProvider
参数的类。
register
,然后将接口注入public function register()
{
$this->app->bind('App\Contracts\SomeInterface', 'App\Logic\ClassName');
if(Request::has('notification_type') && Request::get('notification_type') == 'email') {
$this->app->bind('App\Contracts\SomeInterface', 'App\Logic\SomeotherClassName');
}
}
的{{1}}方法。
在进行测试时,它始终绑定到Controller
。我尝试在__construct()
内访问URL,并在运行ClassName
时始终返回AppServiceProvider
和unit tests
,方法返回为/
,即使从测试中像这样发布到URL。
$this->app->request->getRequestUri();
在使用Postman进行测试时,当我尝试发布GET
时,显示为$this->post('/notification', [
'notification_type' => 'email',
])->assertJson(
'message-push-status' => true,
]);
答案 0 :(得分:1)
这是可能的。 AppServiceProvider或任何其他服务提供商的注册方法有权访问请求参数。
可以如下访问:
public function register()
{
$this->app->bind('SomeInterface', function($app) {
return new SomeClass(request()->some_parameter);
});
}
答案 1 :(得分:0)
您将无法可靠地使用服务提供商内部的当前请求信息。
首先,通常的最佳做法是不直接依赖register()
方法中的应用程序逻辑。您可能会导致竞争状况,其中有尚未注册的依赖项,或者造成不必要的开销(例如,即使不需要任何查询也可以建立数据库连接)。
第二,Laravel's request lifecycle直到 所有服务提供商注册和引导完成之后,才会将当前请求转移到应用程序中。
在不完全知道要完成的业务逻辑的情况下,您至少有两个选择:
使用contextual binding来根据请求对象(例如控制器)为同一接口提供不同的实现。
使用可插入控制器中的工厂或类似促进者风格的对象,并可以根据您的首选逻辑提供适当的依赖性。