PHP - Laravel 依赖注入:将参数传递给依赖构造函数
PHP - Laravel dependency injection: pass parameters to dependency constructor
我正在构建一个 Laravel 项目,在其中一个控制器中,我在一个方法中注入了两个依赖项:
public function pusherAuth(Request $request, ChannelAuth $channelAuth) { ... }
我的问题很简单:如何将参数传递给 $channelAuth
依赖项?
目前我正在使用一些 setter 来传递所需的依赖项:
public function pusherAuth(Request $request, ChannelAuth $channelAuth)
{
$channelAuth
->setChannel($request->input('channel'))
->setUser(Auth::user());
这种方法有哪些替代方法?
P.S。代码需要可测试。
您可以创建和注册自己的服务提供者,并使用构造函数的请求参数创建对象。
我不知道如何在 Laravel 中执行此操作,但在 Symfony2 中,您可以在自己的服务中注入 RequestStack 之类的东西。这是最好的方法,因为您拥有完全可测试的小型服务提供商。
感谢我在这方面的帮助 Laracast discussion 我能够回答这个问题。使用服务提供者,可以通过将正确的参数传递给构造函数来初始化依赖关系。这是我创建的服务提供者:
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function()
{
$request = $this->app->make(Request::class);
$guard = $this->app->make(Guard::class);
return new ChannelAuth($request->input('channel_name'), $guard->user());
});
}
}
您可以像这样解析依赖项时传递参数(作为字符串索引数组):
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function($params)
{
$channelName = $params['channelName'];
$guard = $this->app->make(Guard::class);
return new ChannelAuth($channelName, $guard->user());
});
}
}
然后在控制器中解析时:
public function pusherAuth()
{
$channelAuth = app()->makeWith('Bloom\Security\ChannelAuthInterface', [
'channelName' => $request->input('channel_name')
]);
// ... use $channelAuth ...
}
我正在构建一个 Laravel 项目,在其中一个控制器中,我在一个方法中注入了两个依赖项:
public function pusherAuth(Request $request, ChannelAuth $channelAuth) { ... }
我的问题很简单:如何将参数传递给 $channelAuth
依赖项?
目前我正在使用一些 setter 来传递所需的依赖项:
public function pusherAuth(Request $request, ChannelAuth $channelAuth)
{
$channelAuth
->setChannel($request->input('channel'))
->setUser(Auth::user());
这种方法有哪些替代方法?
P.S。代码需要可测试。
您可以创建和注册自己的服务提供者,并使用构造函数的请求参数创建对象。
我不知道如何在 Laravel 中执行此操作,但在 Symfony2 中,您可以在自己的服务中注入 RequestStack 之类的东西。这是最好的方法,因为您拥有完全可测试的小型服务提供商。
感谢我在这方面的帮助 Laracast discussion 我能够回答这个问题。使用服务提供者,可以通过将正确的参数传递给构造函数来初始化依赖关系。这是我创建的服务提供者:
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function()
{
$request = $this->app->make(Request::class);
$guard = $this->app->make(Guard::class);
return new ChannelAuth($request->input('channel_name'), $guard->user());
});
}
}
您可以像这样解析依赖项时传递参数(作为字符串索引数组):
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function($params)
{
$channelName = $params['channelName'];
$guard = $this->app->make(Guard::class);
return new ChannelAuth($channelName, $guard->user());
});
}
}
然后在控制器中解析时:
public function pusherAuth()
{
$channelAuth = app()->makeWith('Bloom\Security\ChannelAuthInterface', [
'channelName' => $request->input('channel_name')
]);
// ... use $channelAuth ...
}