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

时间:2018-09-07 13:33:57

标签: 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 ...

以前有人遇到过这个问题,并且知道在父类上使用上下文绑定并为所有子级触发它的方法吗?

我知道这可以通过为所有子类实现上下文绑定定义来实现,但这似乎有些笨拙。

谢谢!

1 个答案:

答案 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();
            });
    }
}