如何将 IoC/依赖注入器与静态实例集成


How does laravels IoC/Dependency Injector intsantiate to static instances?

所以这可能是一个相当简单的问题,但我似乎找不到一个非常直接的答案。 我应该可以继续阅读源代码,直到我弄清楚为止,但我希望对这样做的过程有所了解。

我了解 IoC 和依赖注入,我当然在这两个方面都不是很有经验,但我非常了解他们想要实现的目标。 那么这个Laravel是如何实例化到静态实例的呢? 我知道它使用 PHP 反射,但我仍然迷失了从非静态方法到静态方法的部分。 我也知道Laravel不是实现这种设计的唯一框架,但它是我首选和最容易理解的框架。

当您在外观上调用静态方法时,它由Facade类上的魔术__callStatic方法处理。此方法获取为外观提供服务的基础类,并代理对它的静态调用。

让我们看一个示例外观:

<?php
class MyFacade extends Facade {
  public function getFacadeAccessor() { return "MyFacade"; }
}

在这个例子中,当我们以静态方式调用类时,例如: MyFacade::doSomething()类上不存在静态方法。但是,基础Facade基类包含将调用的__callStatic方法。

外观类源代码

public static function __callStatic($method, $args)
{
        $instance = static::resolveFacadeInstance(static::getFacadeAccessor());
        switch (count($args))
        {
                case 0:
                        return $instance->$method();
        // Snipped for brevity...

然后,此方法查找基础类以服务于外观。如果外观上的 getFacadeAccessor 方法返回字符串,则使用应用程序的 IOC 容器中的匹配条目(即 $app['MyFacade'] )。如果我们从 getFacadeAccessor 方法返回一个对象,它将被使用(即 public function getFacadeAccessor(){ return new MyClass(); }

原来是拉拉维尔在引擎盖下实例化类!在这个网站中,这家伙通过使用它来创建一个新的立面,让你更多地了解拉拉维尔的核心。顺便说一下,他解释了山雀是如何工作的!

实际上,这很简单:
1 - 你创建一个类,它通过单个调用从 Laravel 的Facade类扩展,如下所示:

<?php namespace Name'Space;
use Illuminate'Support'Facades'Facade;
class MyClass extends Facade {
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
     protected static function getFacadeAccessor() { return 'myclass'; }
}

。这让拉拉维尔寻找$app['myclass'].因此,ServiceProvider会将myclass绑定到MyClass(根据拉拉维尔的约定)。

2 - 为此,当然,您必须创建一个服务提供商。服务提供商将负责退还您可能想要"变成门面"的类的namespace,在本例中为Name'Space

3 - 您必须在app/config/app.phpproviders数组中注册服务提供商。

现在,如果你更仔细地观察,你会发现Laravel所做的只是导入一个命名空间,并理解它也是一个类。在引擎盖下,它将调用一个实例,但对于用户(程序员)来说,它看起来像一个静态调用。

我希望我已经清楚了!看看我给你的链接,玩得开心!:D