Laravel界面注入装饰的存储库

时间:2015-02-05 14:47:33

标签: php laravel laravel-4

我一直关注真正有用的Laracast装饰库,以便提供从模型中获取数据的不同图层。

在实现它时,我为我的Client模型创建了两个存储库,它们都实现了ClientRepository接口(缓存存储库和数据库存储库)。

然后我做了一个服务提供商并相应地注册了它们。

我以同样的方式为FxRateRepository做了同样的事情。以下是进行注册的服务提供商:

// Providers/DatabaseServiceProvider

public function register()
{
    // Register the fx repositories
    $this->app->singleton('\repositories\FxRateRepository', function()
    {
        return new CacheFxRateRepository(new DbFxRateRepository);
    });

    // Register the client repositories
    $this->app->singleton('\repositories\ClientRepository', function()
    {
        return new CacheClientRepository(new DbClientRepository);
    });
}

现在这一切都很好,并且效果很好......直到我意识到我的DbClientRepository需要一个FxRateRepository的实例。在我的服务提供商I" new up"每个repo的一个实例,并将它们作为依赖项传递给父repos。

显然我无法将界面传递给DbClientRepository,那么我如何告诉Laravel将FxRateRepository的实现注入我的DbClientRepository

我尝试在DbClientRepository的构造函数中进行类型提示,但是我得到了一个异常:

class DbClientRepository implements ClientRepository {
  private $fxRepo;
  public function __construct(FxRateRepository $fxRepo)
  {
      $this->fxRepo = $fxRepo;
  }
}
  

参数1传递给存储库\ DbClientRepository :: __ construct()   必须是存储库\ FxRateRepository的实例,没有给出

我可能错过了IoC容器的一些便利功能,但是对于如何实现这一点感激不尽?

1 个答案:

答案 0 :(得分:2)

DbClientRepository的构造函数中对依赖项进行类型提示是正确的,但是您无法通过new DbClientRepository实例化它,但必须使用{{1}从IoC容器中解析它所以Laravel可以照顾DI:

App::make()

您也可以使用$this->app->singleton('\repositories\ClientRepository', function() { return new CacheClientRepository(App::make('repositories\DbClientRepository'); }); 对象代替Facade:

$app