Laravel 中的服务提供商和 IoC

Service Providers and IoC in Laravel

我正在学习教程 here,并且我 运行 跨越了 ServiceProvider.

中的以下代码块
public function register()
{
    $this->app->bind("chat.emitter", function ()
    {
        return new EventEmitter();
    });
    $this->app->bind("chat.chat", function ()
    {
        return new Chat($this->app->make("chat.emitter"));
    });
    $this->app->bind("chat.user", function ()
    {
        return new User();
    });
    $this->app->bind("chat.command.serve", function ()
    {
        return new Command\Serve($this->app->make("chat.chat"));
    });
    $this->commands("chat.command.serve");
}

public function provides()
{
    return [
        "chat.chat",
        "chat.command.serve",
        "chat.emitter",
        "chat.server"
    ];
}

有几件事让我有些困惑:

  1. 为什么 provides 函数(特别是 "chat.server")中的字符串与 register 函数中绑定的字符串不匹配? provides 不是必须告诉什么 IoC 什么是可用的和什么将被绑定吗?

  2. 当某些东西被 app 绑定时,用于绑定它的字符串的约定是什么?比如上面代码中,"chat.emitter" returns 和 EventEmitter,但是 class EventEmitter 与聊天文件夹无关。实际上,它位于 Evenement 包中。此外,"chat" 不是命名空间的顶部,Formativ 是。为什么不是 "formativ.chat.user"?那么,这里的标准是什么?该字符串的每一段是什么意思?

Why don't the strings in the provides function (specifically "chat.server") match up to what is being bound in the register function? Isn't provides necessary to tell what IoC what is available and what will be bound?

看起来像教程中的 error/typo。 FWIW、用户和服务器(chat.user/chat.server——不匹配的提供者)在您快速编写时很容易交换。

When something is bound by the app, what is the convention for the string used to bind it?

有none。这些服务提供商旨在成为服务的全球(如整个世界)标识符。没有强制的命名约定,据我所知,Laravel 是一个 small/insular 足够的社区,这不是主要问题。如果我要重新分发服务提供商,我会使用类似

的命名约定
companyname_servicename

companyname 部分是我的 company/project 的唯一命名空间,servicename 标识服务的作用。虽然在避免名称空间冲突方面不是 100% 确定性的,但这 确保人们需要不遗余力地选择一个与我的冲突的名称。

您无法从服务名称中获取有关底层 class 的任何信息——即使您可以,IoC 容器的全部意义在于让用户在需要时交换不同的实现。这意味着即使您可以从服务名称派生出 class 名称,您也不知道其他开发人员 and/or 第三方包做了什么。

希望对您有所帮助!