【问题标题】:Laravel DI with interfaces带有接口的 Laravel DI
【发布时间】:2020-10-12 22:57:12
【问题描述】:

我制作了一个存储库模式应用程序,具有存储库和界面:

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

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

我的问题是:

  • 是否需要注意注册顺序?例如,EloquentRepository 类是否应该在 repo,还是 Laravel 自己处理?
  • 如果我在控制器中注入UserRepositoryInterface,即使我没有真正新建一个类,构造函数方法是否也会自动调用?
  • DI 注入“存活”多长时间?如果我将它注入到调用其他控制器并需要相同依赖项的页面控制器中,构造函数是否会调用两次,并在每个控制器中单独操作?
  • 如果我将其称为 App::make() 而不是 DI 有区别吗?

【问题讨论】:

    标签: php laravel dependency-injection


    【解决方案1】:

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

    我不太明白您将在哪里加载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 将被自动解析。

    【讨论】:

    • 对于第一个问题,我的意思是:EloquentRepository 是我的定制课程。文件夹与原始 Laravel 不同,所以如果我要在代码中使用它,我需要通过服务提供者加载所有内容
    【解决方案2】:

    尝试在控制器中抽象化存储库并通过构造函数注入它们。

    像这样:

    
    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)
                });
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2015-03-07
      • 2021-08-13
      • 1970-01-01
      • 2018-04-12
      相关资源
      最近更新 更多