Php Laravel服务容器:父类上的上下文绑定,应用于所有子类

Php Laravel服务容器:父类上的上下文绑定,应用于所有子类,php,laravel,Php,Laravel,我试图基于需要的存储库实现DatabaseConnectionClass实现的上下文绑定 这是必需的,因此从不同数据库获取数据的repositories可以使用相关的连接来实现 我的数据库连接接口也是如此 /** * Interface DatabaseConnectionInterface * * @package App\Database\Connection */ interface DatabaseConnectionInterface { /** * Get

我试图基于需要的存储库实现DatabaseConnectionClass实现的上下文绑定

这是必需的,因此从不同数据库获取数据的repositories可以使用相关的连接来实现

我的数据库连接接口也是如此

/**
 * 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();
            });
    }
}