简体   繁体   English

通过其他软件包注册时,软件包的功能不可用

[英]Functions of Package not Available if Registered Through Another Package

I have a base package that I want to use to manage all my package dependencies. 我有一个基本软件包,我想使用它来管理所有软件包依赖关系。 In building this package my aim is to install and register all dependent packages. 在构建此软件包时,我的目的是安装并注册所有相关的软件包。

I have successfully been able to register the service providers of each package (they show up as loaded when dd($app);). 我已经能够成功注册每个软件包的服务提供商(它们在dd($ app);时显示为已加载)。

Unfortunately I am not able to access any functionality from any of the sub-packages. 不幸的是,我无法从任何子包中访问任何功能。

The error I get is as follows: 我得到的错误如下:

Method <ServiceProviderMethod> does not exist.

The following is the service provider of the main package: 以下是主程序包的服务提供者:

use Illuminate\Support\ServiceProvider;

class BonesServiceProvider extends ServiceProvider {
    protected $defer = false;

    public function boot()
    {
        $this->package('genealabs/bones');
    }

    public function register()
    {
        $this->app->register('GeneaLabs\BonesMacros\BonesMacrosServiceProvider');
        $this->app->register('GeneaLabs\BonesFlash\BonesFlashServiceProvider');
    }

    public function provides()
    {
        return array();
    }
}

If I register the two sub-packages independently in app.php config file, they work just as expected, so I don't think anything is wrong there. 如果我在app.php配置文件中独立注册这两个子包,它们将按预期运行,因此我认为那里没有任何问题。 My guess is that I am not exposing something through the main package, but I have no idea what I'm missing. 我的猜测是我没有通过主程序包暴露某些东西,但是我不知道自己缺少什么。

Any thoughts on what might be causing this? 有什么想法可能导致这种情况?

Update: For debugging I created the main package in workbench in a new Laravel app, to keep namespace "contamination" to a minimum. 更新:为了调试,我在新的Laravel应用程序的工作台中创建了主程序包,以将名称空间的“污染”保持在最低水平。 I was able to install it, but now its throwing errors on the $this->register lines that it cannot find the namespaces listed, even though those packages were developed under those namespaces. 我能够安装它,但是现在它在$ this-> register行上抛出错误,即使这些软件包是在那些命名空间下开发的,它也找不到列出的命名空间。

I updated the register method in the main package's service provider as follows: 我在主程序包的服务提供程序中更新了register方法,如下所示:

public function register()
{
    $bonesMacroServiceProvider = new BonesMacrosServiceProvider($this->app);
    $bonesFlashServiceProvider = new BonesFlashServiceProvider($this->app);
    $this->app->register($bonesMacroServiceProvider);
    $this->app->register($bonesFlashServiceProvider);
}

But this had no use either, still receiving the same error, that it can't find the methods in the sub-packages. 但这也没有用,仍然收到相同的错误,即无法在子包中找到方法。

Update 2 更新2

After undoing the last bit there with the instanciation in the register method, I did some more investigating. 用register方法的实例化消除了最后一点之后,我做了一些进一步的研究。 Now dd()'ing the $app variable shows that none of my packages are actually registered, event the main package I manually included in app.php. 现在dd()对$ app变量的显示表明,我的软件包实际上都没有注册,事件是我手动包含在app.php中的主软件包。 So far it appears that: 到目前为止,看来:

  • The main package fails to register, because it errors out on composer update. 主软件包无法注册,因为它会在作曲家更新时出错。
  • Composer update complains that it can't see the dependent packages' namespace to register them. Composer更新抱怨它看不到相关包的名称空间来注册它们。
  • The dependent packages' namespace isn't available for registering, because composer hasn't installed them yet. 依赖包的名称空间不可注册,因为composer尚未安装它们。

This seems like a vicious catch-22. 这似乎是一个恶性的22。 Is there anyway to avoid this? 反正有避免这种情况吗? Could I check for namespace and only attempt to register a package if the namespace exists? 我可以检查名称空间,仅在名称空间存在的情况下尝试注册软件包吗?

Update 3 更新3

By modifying the register() method in the main package's service provider, I was able to get composer to run successfully now: 通过修改主程序包的服务提供程序中的register()方法,我能够使composer现在成功运行:

public function register()
{
    if (class_exists('GeneaLabs\BonesMacros\BonesMacrosServiceProvider')) {
        $this->app->register('GeneaLabs\BonesMacros\BonesMacrosServiceProvider');
    }
    if (class_exists('GeneaLabs\BonesFlash\BonesFlashServiceProvider')) {
        $this->app->register( 'GeneaLabs\BonesFlash\BonesFlashServiceProvider' );
    }
}

However, the original issue still remains that I am unable to access any of the functionality in the sub-packages. 但是,原始问题仍然存在,我无法访问子软件包中的任何功能。

this post is a few months old but I think this is helpful here. 这篇文章已有几个月的历史了,但我认为这对您有所帮助。 I do it this way (laravel 4.2): 我这样做(laravel 4.2):

in my service provider: 在我的服务提供商中:

// for adding package alias
use Illuminate\Foundation\AliasLoader;

public function boot() {

    // ...laravel stuff

    // register the service provider for the child package
    $this->app->register('Vendor\Package\PackageServiceProvider');
}


public function register() {

    // loader for config namespaces
    $loader = $this->app['config']->getLoader();

    // get the config environment name
    $env = $this->app['config']->getEnvironment();

    // add the folder to the package config files to the config loader namespace
    $loader->addNamespace('package',__DIR__.'/../../../../../../app/config/packages/vendor/package');

    // perform the "override" (load config data)
    $configs = $loader->load($env,'config','package');

    // override config data in global config array
    $this->app['config']->set('package::config',$configs);

    // add the alias for the child package
    AliasLoader::getInstance()->alias('Former', 'Depends\On\Package');
}

This way you can keep the child package untouched because you can override the config file laravelish style. 这样,您可以保持子包不变,因为您可以覆盖配置文件的laravelish样式。

So everything included like alias, service provider and config file (optionally overwritten) 因此,所有内容都包括别名,服务提供商和配置文件(可以选择覆盖)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM