在laravel 5中

时间:2016-08-24 02:25:45

标签: php laravel

让我们假设我有一个这样的界面:

interface RepositoryInterface{
    public function getById($id);
}

此接口由X个类实现。

举个例子:

class SqliteRepository implements RepositoryInterface{
    public function getById($id)
    {
        return $id;
    }
}

我在config文件夹中也有一个配置文件(请注意,这不是database.php文件,它是完整的不同文件):

'default'  => 'sqlite',

'connections' => [
    'sqlite' => [
        'database' => env('DB_DATABASE', storage_path('database.sqlite')),
    ],

    'some_other_db' => [
        'database' => env('DB_DATABASE', storage_path('some_other_db')),
    ],
],

connections本身可以是任何东西。数据库,API,甚至是csv文件。

这背后的主要思想是我可以通过更改配置来切换存储介质。不要问我为什么我没有使用默认的laravel database文件,这是一个很长的故事。

问题:

我希望能够基于该配置文件将RepositoryInterface的不同实现注入到控制器中,类似于以下内容:

if(Config::get('default') == 'sqlite')
{
    // return new SqliteRepository
}

显然,这里的方式是服务提供商。但是,我不确定如何处理这个问题。 我的意思是我可以按照以下方式做点什么:

class RepositoryServiceProvider extends ServiceProvider
{
    public function register()
    {
        if(Config::get('storage') == 'sqlite')
        {
            $this->app->singleton(SqliteRepository::class, function ($app) {
                return new SqliteRepository(config('SqliteRepository'));
            });
        }

    }
}

但感觉有点不对,更何况它给了我零错误控制。我不想在ServiceProvider中抛出错误。我需要某种上下文绑定或类似的东西。我已经阅读了the documentation regarding contextual binding但它并不是我正在寻找的内容,因为它指的是基于控制器使用它们的类的具体实现。

我更多地考虑了一种抽象的工厂类型的交易,但是,我再也不确定如何适应laravel的做事方式。

任何指向正确方向的人都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

interface RepositoryInterface{
    public function getById();
}

...
...

class SqliteRepository implements RepositoryInterface{
    public function getById()
    {
        return 1;
    }
}

...
...

class CsvRepository implements RepositoryInterface{
    public function getById()
    {
        return 2;
    }
}

...
...

class MonkeyPooRepository implements RepositoryInterface{
    public function getById()
    {
        return 3;
    }
}

...
...

use RepositoryInterface;
class Controller {

    public function __construct( RepositoryInterface $repo ) {
        $this->repo = $repo;
    }

    public function index()
    {
        dd($this->repo->getById());
    }

}

在您的应用提供商处;

public function register()
{
    $this->app->bind( RepositoryInterface::class, env('REPOSITORY', 'MonkeyPooRepository' ) );
}

索引方法将返回(int)3