Laravel:覆盖 Bundle 的服务提供者

Posted

技术标签:

【中文标题】Laravel:覆盖 Bundle 的服务提供者【英文标题】:Laravel: Overriding a Bundle's Service Providers 【发布时间】:2014-07-10 11:24:04 【问题描述】:

我有一个项目使用 Laravel 的 Sentinel 包。

前段时间,我问了一个关于extending a model provided in the bundle的问题。我接受的答案有效,但它需要在供应商文件夹中编辑捆绑包的代码。

从那时起,我运行了一个composer update 命令并且我应用的更改被覆盖(这并不奇怪)。

我现在对 laravel 的工作原理有了更多了解,因此我能够追溯我的应用程序引用捆绑服务的端点。在我的config/app.php 文件中,我有服务提供商参考:

'Sentinel\SentinelServiceProvider',

SentinelServiceProvider 服务有一个register 方法注册RepoServiceProvider,这是我需要重写的类。

我的计划是创建两个新文件:ExtendedSentinelServiceProvider.phpExtendedRepoServiceProvider.php

ExtendedRepoServiceProvider.php 文件中,我可以将用于用户存储库绑定的类替换为我的自定义用户类:

    // Bind the User Repository
    $app->bind('Sentinel\Repo\User\UserInterface', function($app)
    
        return new ExtendedSentryUser( // This is my custom model that I want the ExtendedRepoServiceProvider to use
            $app['sentry']
        );
    );

ExtendedSentinelServiceProvider.php 文件中,我会将现有的RepoServiceProvider 类引用替换为我新修改的ExtendedRepoServiceProvider 类:

public function register()

    $loader = \Illuminate\Foundation\AliasLoader::getInstance();
    $loader->alias('Sentry', 'Cartalyst\Sentry\Facades\Laravel\Sentry');

    $repoProvider = new ExtendedRepoServiceProvider($this->app); // This would be my new ExtendedRepoServiceProvider class
    $repoProvider->register();

    $formServiceProvider = new FormServiceProvider($this->app);
    $formServiceProvider->register();

然后,我会将config/app.php 文件中的服务提供者引用替换为新的ExtendedSentinelServiceProvider 类:

'providers' => array(
    ...
    'Sentinel\ExtendedSentinelServiceProvider',
    ...
),

我的问题是,作为一种能够将我的修改存储在我的应用程序目录中而不是修改供应商代码的方式,这是否有意义?当涉及到名称间距时,这会成为一个问题吗?有更好的方法吗??

任何帮助都会非常感谢

【问题讨论】:

不是这样的答案 - 但你的方法对我来说看起来不错。唯一的事情是,一旦您需要开始更改软件包以满足您的需求,也许最好只编写自己的实现 - 尤其是像您的用户这样重要和独特的东西。 感谢您的评论。我考虑编写自己的实现,但这是我的第一个 laravel 项目,所以我不知道我是否可以可靠地做到这一点。我想如果我将来使用 Sentry(很有可能),我会以 Sentinel 为例编写自己的实现。 提醒任何使用 Sentinel 捆绑包的人;我在 github 上给 rydurham 发了消息,他发布了一个新版本的包,允许您通过配置文件创建其他字段。 github.com/rydurham/Sentinel/commit/… 【参考方案1】:

您不应该遇到名称间距问题。然而,另一种选择 - 特别是如果您要添加可能对其他人通常有用的功能 - 将在 github 上分叉项目,然后在 composer.json 的“存储库”属性中包含对您的 git 项目的引用。例如,您可以添加:

"repositories": [
    
        "type": "git",
        "url": "git@github.com:your-user/Sentinel.git"
    
],

然后,composer 会在安装/更新时查看您的 fork。

【讨论】:

以上是关于Laravel:覆盖 Bundle 的服务提供者的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 容器中覆盖单例

如何设置 Laravel Boilerplate phpunit 以在 Homestead 环境中提供代码覆盖

如何为 webpack 构建的生产 react bundle.js 提供服务?

终端上深信服EDR的移除

Sonata Admin Bundle + Sonata User Bundle:覆盖登录表单

Laravel Nginx 覆盖 phpMyAdmin