Laravel DI带接口

时间:2018-01-13 15:06:55

标签: php laravel dependency-injection

我制作了一个存储库模式应用程序,有一个repo和接口:

class UserRepository extends EloquentRepository implements UserRepositoryInterface
{
    public function __construct()
    {
        $this->model = new User();
    }
    ...
}

存储库和接口以及扩展类及其接口在服务提供程序中注册,并在应用程序启动时调用。

我的问题是:

  • 是否需要注意注册顺序?例如,应该在EloquentRepository类之前加载 回购,还是Laravel独自处理它?<​​/ li>
  • 如果我在控制器中注入UserRepositoryInterface,是否会自动调用构造函数方法,即使我没有真正新建一个类?
  • DI注射多长时间&#34;生活&#34;?如果我将它注入一个调用其他控制器并需要相同依赖关系的页面控制器,那么构造函数是否会调用两次,并在每个控制器中单独运行?
  • 如果我将其称为App::make()而不是DI,那会有区别吗?

2 个答案:

答案 0 :(得分:2)

  

是否需要注意注册的顺序?例如,应该在repo之前加载EloquentRepository类,还是Laravel自己处理它?<​​/ p>

我不太明白你将EloquentRepository加载到哪里(从发布的代码中)看起来你只是在扩展它。这应该不是问题。

  

如果我在控制器中注入UserRepositoryInterface,即使我没有真正新建一个类,是否会自动调用构造函数方法?

是。 Laravel的大多数主要类(包括控制器)都考虑了DI,并且依赖关系将自动解决。

话虽如此,由于您正在注入接口,并且默认情况下接口无法初始化为类,因为它没有实现 - 您需要先bind an implementation to the interface才能使用它。

  

DI注入“活”了多长时间?如果我将它注入一个调用其他控制器并需要相同依赖关系的页面控制器,构造函数是否会调用两次,并在每个控制器中单独运行?

我的理解是,在初始化下一个控制器时,将创建该类的新实例。除非你绑定一个类as a singleton

  

如果我将其称为App :: make()而不是DI,那会有区别吗?

App::make(some::class)会自动解决类some的依赖关系。

例如:

namespace App;

use App\Dependancy;

class Test 
{
    protected $d;

    public function __construct(Dependancy $d) 
    {
        $this->d = $d;
    }
}

如果您在控制器中调用它:$a = new \App\Test(),您将收到\App\Test构造函数期望类Dependency作为第一个参数的错误。

但如果你这样初始化:$a = \App::make(\App\Test::class) Dependency将自动解析。

答案 1 :(得分:0)

尝试在控制器中使存储库抽象,然后通过构造函数将其注入。

在这里像这样:


public function __construct(EloquentRepository $repository)
{
   $this->repository = $repository;
}


在AppServiceProvider中,您可以注入所需的存储库。

   public function boot()
    {
        // provides any Repository in SomeController

        $this->app->when(SomeController::class)
            ->needs(EloquentRepository::class)
            ->give(function (Application $app) {
                return $app->make(SomeRepositoryInterface::class)
            });
    }