php - Laravel 服务容器:父类的上下文绑定,适用于所有子类
问题描述
我试图基于需要它的存储库来实现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 ...
以前有没有人遇到过这个问题,并且知道在父类上使用上下文绑定并为所有子类触发它的方法?
我知道这可以通过为所有子类实现上下文绑定定义来实现,但这似乎有点笨拙。
提前致谢!
解决方案
据我所知,因为 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();
});
}
}
推荐阅读
- shell - grep - 匹配前 n 行的字符串
- c# - 删除成绩单数据 C# 中的时间模式
- javascript - Javascript chrome 扩展在新标签页中不起作用
- python - 如何阻止熊猫按字母顺序对数据框中的列进行自动排序?
- ag-grid - 行详细信息面板
- reporting-services - SSRS 表达式,用于获取当前周周日至周六
- flutter - Flutter 有两个 SliverPersistentHeader 一个接一个堆叠
- html - 更新 VSCode html 制表符间距
- python - 我将 permission_required 设置为“is_staff”,但出现错误 403 权限被拒绝
- python - 更改桌面屏幕方向