laravel 是否可以覆盖一个包的依赖注入?

q35jwt9p  于 2023-04-22  发布在  其他
关注(0)|答案(2)|浏览(101)

我正在创建一个包,想覆盖Migrate命令,但似乎不知道怎么做。看起来Laravel本身比我的ServiceProvider有更高的优先级,有没有办法在覆盖中获得优先级,并通过包获得我的自定义类?

w7t8yxp5

w7t8yxp51#

我尝试使用ServiceProviderregister()方法来绑定Illuminate\Database\Migrations\Migrator的自定义实现,但它不起作用。
尽管这并不美观,但我认为您可以使用composer来自动加载您需要覆盖的任何类的自定义实现。
例如,假设您想要覆盖Illuminate\Database\Migrations\Migrator
编写这个类的新实现并保存在某个地方...例如app/Overrides/Illuminate/Database/Migrations/Migrator.php
在此文件中,覆盖vendor类**,保留vendor命名空间**。

// app/Overrides/Illuminate/Database/Migrations/Migrator.php
namespace Illuminate/Database/Migrations;

class Migrator
{
    ....
}

然后,在你的composer.json文件中,你需要显式地声明你希望自动加载THIS类而不是laravel的类,并且从自动加载中排除laravel自己的类。

"autoload": {
    ...
    "exclude-from-classmap": ["vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php"],
    "files": ["app/Overrides/Illuminate/Database/Migrations/Migrator.php"]
    ...
},

最后,运行composer dumpautoload。每次使用composer require添加新包时都要再次运行它。

sczxawaw

sczxawaw2#

我发现了为什么替换不起作用,原来的服务提供者被延迟了,这意味着它的注册和 Boot 方法在需要MigrateCommand类之前被调用。当我延迟我的服务提供者时,它开始工作的方式是一样的!

class MigrateServiceProvider extends ServiceProvider implements DeferrableProvider
{
    public function register(): void
    {
        $this->app->scoped(Migrator::class, function(Application $app) {
            return $app->make('migrator');
        });
    }

    public function boot(): void
    {
        if ($this->app->runningInConsole()) {
            $this->commands([
                NewMigrateCommand::class
            ]);
        }
    }

    public function provides(): array
    {
        return [NewMigrateCommand::class, Migrator::class];
    }
}

相关问题