首页 > 解决方案 > 升级到 5.8 后 IoC 解决问题

问题描述

希望有人可以帮助我,

我正在从版本 5.7 更新到 5.8,现在我的存储库设置存在问题。

我正在使用存储库模式,对于每个存储库,我们都有一个合同。我有一个服务提供者(设置为延迟)将合同绑定到存储库,因此当类型提示控制器中的接口/合同时,存储库被注入。

我们还有一个服务提供者(也设置为延迟),当存储库被解析时,它会从配置文件中获取一些配置数据并调用存储库上的方法来设置属性。

这一切在 5.7 上都很好用,但升级到 5.8 后就不行了。如果我将控制器切换为类型提示存储库而不是合同它可以工作,但显然如果/当我们更改存储库时,我们将不得不修改所有引用它的地方,这完全违背了对接口进行编码和注入它的目的。

希望我已经解释得足够好!

有没有人反对这个或类似的?我检查了升级说明,5.8 不再使用 defer 属性,因为它实现了我正在做的接口,但我看不到其他任何东西,我正在努力进一步调试它。

https://laravel.com/docs/5.8/upgrade#deferred-service-providers

任何人能提供的任何帮助都会很棒。

如果我切换回 5.7 没有问题,或者如果使用实际的存储库并在控制器中输入提示没有问题,则仅在使用合同/接口时才会发生

这是存储库设置其属性的服务提供者

<?php

namespace App\Providers\Repositories\Erp;

use App\Models\ERP_OLTP\WorkOrderStatus as WorkOrderStatusModel;
use App\Repositories\Erp\EloquentMaterialRequirements;
use Illuminate\Contracts\Config\Repository as ConfigRepositoryInterface;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;

class MaterialRequirementsServiceProvider extends ServiceProvider implements DeferrableProvider
{

    public function register()
    {
        $this->app->resolving(
            EloquentMaterialRequirements::class,
            function (EloquentMaterialRequirements $repo, $app) {
                $config = $app[ConfigRepositoryInterface::class]->get('materialRequirements');

                $statusIds = array_reduce(
                    $config['workOrderStatuses'],
                    function ($acc, $statusCode) {
                        $acc[] = WorkOrderStatusModel::STATUS[$statusCode];

                        return $acc;
                    },
                    []
                );

                $repo->setDemandStatusIds($statusIds);
                $repo->setDemandWeekCount($config['weekCount']);
                $repo->setAverageUsageWeekCount($config['averageWeeklyUsageMaxAgeWeeks']);
            }
        );
    }

    public function provides()
    {
        return [
            EloquentMaterialRequirements::class,
        ];
    }
}

这是要绑定到合同的存储库的服务提供者

<?php

namespace App\Providers;

use Illuminate\Contracts\Config\Repository as ConfigRepositoryInterface;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class ErpRepositoriesServiceProvider extends ServiceProvider implements DeferrableProvider
{
    public function register()
    {
        foreach ($this->getBindings() as $contract => $implementation) {
            $this->app->bind($contract, $implementation);
        }
    }

    public function provides()
    {
        $services = [];

        foreach (array_keys($this->getBindings()) as $contract) {
            $services[] = $contract;
        }

        return $services;
    }

    private function getBindings(): array
    {
        return $this->app[ConfigRepositoryInterface::class]->get('repositories.bindings');
    }
}

这是 config.repositories,我删除了其他存储库以缩小它

<?php

use App\Contracts\Erp\Repositories as Contracts;
use App\Managers\Erp\Repositories as Managers;
use App\Repositories\Erp as Repositories;

return [
    'bindings' => [
        Contracts\MaterialRequirements::class => Repositories\EloquentMaterialRequirements::class,
    ],
];

它根本不会调用 MaterialRequirementsServiceProvider ,或者如果它调用它,它不会解析 EloquentMaterialRequirements::class 并因此设置属性。我没有错误,没有例外,没有什么可做的

标签: laravelioc-containerlaravel-5.8

解决方案


推荐阅读