服务提供商内部的Laravel 5存储库

时间:2015-07-16 12:00:37

标签: php laravel-5

我的laravel 5项目中存在以下问题。我有一个名为MacroServiceProvider.php的表单宏的服务提供程序。有些宏应该从数据库接收数据,我目前正在使用该模型并以雄辩的方式获得结果,但我想使用存储库,所以我创建了我的存储库,但我不能将它直接注入我的服务提供者。

我想要这样的事情:

...
public function register(MyRepoInterface $repo)
    {
        $registers = $repo->findAll();
        Form::macro...
    }
...

我该怎么做?

感谢。

1 个答案:

答案 0 :(得分:20)

我认为你不能做你所要求的事情,我认为你误解了提供者的工作方式以及他们的目标。

在提供程序中,您通常会说接口和实现之间的绑定是什么,因此当您在应用程序代码中执行依赖项注入时,它可以正常工作。我很确定他们不打算做真正的事情。

对于你对代码的看法,我想象这样的事情:

  • 存储库界面(MyRepoInterface),其中包含使用Eloquent的真实实现(例如EloquentMyRepo
  • 外观,说Macro,以便您可以Macro::myMacro1()Macro::myMacro2()等。
  • 方法myMacro1()myMacro2()等使用存储库从db获取一些数据,然后从Form facade
  • 调用一些方法

如果我是对的,那么我建议这样的事情。

存储库

使用

在文件MyRepoInterface.php中定义界面
interface MyRepoInterface 
{
    public function findAll();

    // ... your other repo methods
}

以及带有

的实施EloquentMyRepo.php
class EloquentMyRepo implements MyRepoInterface
{
    public function findAll()
    {
        // ... do what you need
    }
}

门面

使用此

定义外观文件MacroFacade.php
use Illuminate\Support\Facades\Facade;

class MacroFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'macro';
    }
}

服务类

在文件MacroService.php中定义宏服务类,您可以在其中使用依赖项注入并访问存储库。在本课程中,您可以定义myMacro1() ...方法。

class MacroService
{
    protected $myRepo;

    public function __construct(MyRepoInterface $myRepo)
    {
        $this->myRepo = $myRepo;
    }

    public function myMacro1()
    {
        // access the repo
        $items = $this->myRepo->findAll();
        // ... do something with $items and finally return a string
        return Form::macro(...);
    }

    public function myMacro2($arg1, $arg2)
    {
        // ... use the parameters to do something else
    }
}

绑定

Providers/AppServiceProvider.php文件中,转到register()方法并添加

public function register()
{
    // ...
    $this->app->bind('App\MyRepoInterface', 'App\EloquentMyRepo');
    // ...
}

因此,当您在依赖注入中使用MyRepoInterface时,Laravel知道它必须使用EloquentMyRepo的实例。

现在,让我们为您的宏服务创建一个服务提供者。创建一个文件Providers/MacroServiceProvider.php并输入

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class MacroServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('macro', 'App\MacroService');
    }
}

现在,当我们需要注册为macro的外观时,会使用MacroService的实例。

配置

我们最终需要对配置进行一些更改。打开config/app.php文件,添加新提供商

...
'providers' => [
    ...
    'App\Providers\AppServiceProvider',
    ...
    'App\Providers\MacroServiceProvider',
],

(请注意MacroServiceProviderAppServiceProvider后声明。)

添加外观的别名:

'aliases' => [
    ...
    'Macro' => 'App\MacroFacade',
],

完成!

会发生什么

我们假设您致电

...
Macro::myMacro1();
...
你的代码中的

。如何调用正确的方法?

  1. Macro是由MacroFacade
  2. 处理的别名
  3. 通过macro <{1}} getFacadeAccessor()方法在IoC中注册了MacroFacade名称
  4. MacroServiceProvider已将MacroService类注册为macro的实施
  5. 必须创建MacroService的实例,但它具有MyRepoInterface作为依赖
  6. AppServiceProvider表示Laravel在需要EloquentMyRepo时使用MyRepoInterfice
  7. 因此创建了EloquentMyRepo的实例,它用于创建MacroService的实例
  8. Macro已解析为MacroService
  9. 的实例
  10. Laravel调用该实例的myMacro1()方法
  11. 我希望这可以澄清一下会发生什么。