第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在控制器類中注入容器

在控制器類中注入容器

PHP
qq_笑_17 2021-12-03 15:03:21
我正在將我的應用程序從 Slim/3 遷移到 Slim/4。也許我很困惑,因為同樣的東西有無窮無盡的語法,但我寫了這個:use DI\Container;use Slim\Factory\AppFactory;use Slim\Psr7\Request;use Slim\Psr7\Response;require dirname(__DIR__) . '/vendor/autoload.php';class Config extends Container{}class Foo{    protected $config;    public function __construct(Config $config)    {        $this->config = $config;    }    public function __invoke(Request $request, Response $response, array $args): Response {        var_dump($this->config->get('pi'));        return $response;    }}$config = new Config();$config->set('pi', M_PI);var_dump($config->get('pi'));AppFactory::setContainer($config);$app = AppFactory::create();$app->get('/', \Foo::class);$app->run();...它沒有按我預期的那樣工作,因為我得到了兩個完全不同的容器實例(通過在 中設置斷點來驗證\DI\Container::__construct()):我用$config = new Config();.一個在 at 自動創(chuàng)建,$app->run();然后作為參數(shù)傳遞給\Foo::__construct().我做錯了什么?
查看完整描述

3 回答

?
絕地無雙

TA貢獻1946條經(jīng)驗 獲得超4個贊

容器嘗試解析(并創(chuàng)建)類的新實例\DI\Container,因為這不是 Slim 使用的接口。相反,嘗試聲明 PSR-11 ContainerInterface。然后 DIC 應該傳遞正確的容器實例。


例子


use Psr\Http\Message\ServerRequestInterface;


public function __construct(ContainerInterface $container)

{

    $this->container = $container;

}

相同的“規(guī)則”適用于請求處理程序接口。


完整示例:


use Psr\Container\ContainerInterface;

use Psr\Http\Message\ResponseInterface as Response;

use Psr\Http\Message\ServerRequestInterface as Request;


class Foo

{

    private $container;


    public function __construct(ContainerInterface $container)

    {

        $this->container = $container;

    }


    public function __invoke(

        Request $request,

        Response $response,

        array $args = []

    ): Response {

        var_dump($this->container);

    }

}

最后一點:注入容器是一種反模式。請改為在構造函數(shù)中顯式聲明所有類依賴項。


為什么注入容器(在大多數(shù)情況下)是一種反模式?


在 Slim 3 中,“服務定位器”(反模式)是注入整個(Pimple)容器并從中獲取依賴項的默認“風格”。


服務定位器(反模式)隱藏了類的真正依賴。


服務定位器(反模式)也違反了 SOLID 的控制反轉 (IoC) 原則。


問:我怎樣才能讓它變得更好?


A:使用composition和(顯式)構造函數(shù)依賴注入。


依賴注入是一種將其協(xié)作者傳遞給對象的編程實踐,而不是對象本身創(chuàng)建它們。


由于斯利姆4您可以使用現(xiàn)代化的DIC像PHP-DI和league/container與真棒“自動裝配”功能。這意味著:現(xiàn)在您可以在構造函數(shù)中顯式聲明所有依賴項,并讓 DIC 為您注入這些依賴項。


更明確地說:“組合”與 DIC 的“自動裝配”功能無關。您可以將組合與純類一起使用,而無需容器或其他任何東西。自動裝配功能僅使用PHP 反射類為您自動解析和注入依賴項。


查看完整回答
反對 回復 2021-12-03
?
達令說

TA貢獻1821條經(jīng)驗 獲得超6個贊

這是 PHP-DI 如何自動注冊自身的結果。在撰寫此答案時,PHP-DI 容器DI\Container在創(chuàng)建時將自身自動注冊到 key以及三個實現(xiàn)的接口(請參閱Container.php 的這些行)。因此,如果您針對構造函數(shù)參數(shù)DI\Container或它實現(xiàn)的三個接口之一(包括Psr\Container\ContainerInterface)鍵入提示,則 PHP-DI 能夠自行解析。


?問題是使用self::class(該文件的第 110 行)使DI\Container密鑰以某種方式進行了硬編碼,因此盡管您正在創(chuàng)建DI\Container( Config) 的子類,但容器仍像以前一樣注冊到相同的密鑰。解決這個問題的一種方法是讓容器知道它Config也應該由自己解決。我看到兩個選項:


將容器注冊到與其類名相同的鍵,就像做什么DI\Container一樣(這似乎是正確的方法)

實例化后手動注冊容器

這是一個完全有效的示例:


<?php

require '../vendor/autoload.php';

use DI\Container;

use Slim\Factory\AppFactory;


use Psr\Container\ContainerInterface;

use DI\Definition\Source\MutableDefinitionSource;

use DI\Proxy\ProxyFactory;


class Config extends Container

{

    public function __construct(

        MutableDefinitionSource $definitionSource = null,

        ProxyFactory $proxyFactory = null,

        ContainerInterface $wrapperContainer = null

    ) {

        parent::__construct($definitionSource, $proxyFactory, $wrapperContainer);

        // Register the container to a key with current class name

        $this->set(static::class, $this);

    }

}


class Foo

{

    public function __construct(Config $config)

    {

        die($config->get('custom-key'));

    }

}


$config = new Config();

$config->set('custom-key', 'Child container can resolve itself now');

// Another option is to not change Config constructor,

// but manually register the container in intself with new class name

//$config->set(Config::class, $config);

AppFactory::setContainer($config);

$app = AppFactory::create();

$app->get('/', \Foo::class);

$app->run();

請注意:正如最佳實踐所建議的那樣,您不應針對具體類(DI\Container或您的Config類)鍵入提示,而應考慮針對接口 ( Psr\Container\ContainerInterface)鍵入提示。


查看完整回答
反對 回復 2021-12-03
?
滄海一幻覺

TA貢獻1824條經(jīng)驗 獲得超5個贊

問題是濫用了名為autowiring的 PHP-DI 功能:


自動裝配是一個奇特的詞,它代表了一些非常簡單的東西:容器自動創(chuàng)建和注入依賴項的能力。


為了實現(xiàn)這一點,PHP-DI 使用 PHP 的反射來檢測構造函數(shù)需要哪些參數(shù)。


如果您使用工廠方法來創(chuàng)建容器,您可以禁用自動裝配并停止“奇怪”行為:


$builder = new ContainerBuilder(Config::class);

$builder->useAutowiring(false);

$config = $builder->build();

但我想更好的解決方案是學習如何正確使用自動裝配:)


我忽略了所有這些細節(jié),因為我的代碼最初是為 Slim/3 編寫的,它使用Pimple作為硬編碼默認容器。我錯誤地認為它們的工作方式相似,但盡管是容器解決方案,但兩個庫卻大不相同。


查看完整回答
反對 回復 2021-12-03
  • 3 回答
  • 0 關注
  • 222 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號