我正在尝试根据需要的 DatabaseConnectionClass 实现的上下文绑定。
这是必需的,以便邮局可以使用相关的连接从不同的数据库中获取数据。
我的数据库连接界面是这样的
/**
* Interface DatabaseConnectionInterface
*
* @package App\Database\Connection
*/
interface DatabaseConnectionInterface {
/**
* Get the database connection
*
* @return Connection
*/
public function getConnection(): Connection;
}
我的基本存储库
/**
* Class MiRepository
*
* Base repository centralising connection injection
*
* @package App\Repositories\Mi
*/
class MiRepository {
/**
* The connection to the database
*
* @var DatabaseConnectionInterface
*/
protected $connection;
/**
* MiRepository constructor.
*
* @param DatabaseConnectionInterface $connection
*/
public function __construct(DatabaseConnectionInterface $connection){
$this->connection = $connection->getConnection();
}
}
存储库扩展
/**
* Class SchemeRepository
*
* @package App\Mi\Repositories
*/
class SchemeRepository extends MiRepository {
/**
* Find and return all stored SchemeValidator
*
* @return Scheme[]|NULL
*/
public function findAll(): ?array {
$results = $this->connection->select('EXEC [webapi_get_products_schemes]');
if(empty($results)){
return NULL;
}
$schemes = array();
foreach($results as $result){
$schemes[] = Scheme::create($result->SCHEMENAME);
}
return $schemes;
}
}
服务容器绑定
/**
* Class MiServiceProvider
*
* @package App\Providers
*/
class MiServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->when(MiRepository::class)
->needs(DatabaseConnectionInterface::class)
->give(function(){
return new MiDatabaseConnection();
});
}
}
问题是,当我尝试注入基础存储库的扩展名时,我不认为上下文绑定被触发并且出现异常
Target [App\\Common\\Database\\Connection\\DatabaseConnectionInterface] is not instantiable ...
以前有人遇到过这个问题,并且知道在父类上使用上下文绑定并为所有子级触发它的方法吗?
我知道这可以通过为所有子类实现上下文绑定定义来实现,但这似乎有些笨拙。
谢谢!
答案 0 :(得分:0)
据我所知,由于PHP和依赖项注入总体上依赖于反射来了解构造函数正在寻找的类,因此基本上是在进行字符串模式匹配以找到正确的绑定。由于您尚未为扩展类定义绑定字符串,因此无法找到相关的绑定函数。因此,我怀疑您想做的事行不通。
避免过多重复代码的变通方法可能是:
public function register()
{
foreach($repo in ['Foo', 'Bar', 'Baz']) {
$this->app->when($repo . Repository::class)
->needs(DatabaseConnectionInterface::class)
->give(function () use ($repo) {
$theClass = $repo . 'DatabaseConnection';
return new $theClass();
});
}
}