繁体   English   中英

是否可以使用PHP-DI定义代替Slim 3中内置在IoC中的Eloquents胶囊管理器?

[英]Is it possible to use PHP-DI definitions instead of Eloquents Capsule Managers Built in IoC within Slim 3?

我目前正在研究使用php-di桥提供依赖项的苗条3应用程序。 一切在控制器内都可以正常工作,但是,在尝试向模型观察者添加依赖项时遇到了一个问题。 Eloquents的胶囊管理器有自己的容器,因此我无法通过依赖项(未注入)而不会引发错误。

当前设置:

$app = new \App\App; // extends \DI\Bridge\Slim\App
$container = $app->getContainer();

$capsule = new Capsule;
$capsule->addConnection($settings['settings']['db']);
$capsule->setEventDispatcher(new Dispatcher());
$capsule->setAsGlobal();
$capsule->bootEloquent();

// Sale model extends eloquent model
Sale::observe(new SaleObserver($container));

SaleObserver类别:

class SaleObserver {

    protected $container;

    public function __construct($container){
        $this->container = $container;
    }
    public function saving(Sale $sale){

        // Mail logic using container

    }

}

这给了我从我的SaleObserver触发的错误:

Unresolvable dependency resolving [Parameter #0 [ <required> $container ]]

我认为问题在于,我雄辩的自己的容器正在解决SaleObserver,这使我无法通过我的PHP-DI“ $ container”。 如果不采用骇人听闻的方法,在slim 3中是否可能发生类似的事情?

我正在使用容器进行测试,以查看是否可以通过某些内容,但是,我的主要目标是仅通过我的邮件定义,因为它已经设置了所有配置。

更新:

我以前曾尝试在SaleObserver类中键入提示,如下所示,希望php-di会无济于事。

use App\Mail\Contracts\MailerInterface;

class SaleObserver {

    protected $mail;

    public function __construct(MailerInterface $mail){

        $this->mail = $mail;

    }

    public function updating(Sale $sale){

        // Send Mail logic

    }

}

我最终得到另一个错误,该错误表明php-di自动接线不适用于未连接到路由的类,即使将自动接线设置为true也是如此,因为注入的参数不会像应有的那样自动实例化。

这显示了错误:

Uncaught ArgumentCountError: Too few arguments to function

我正在使用的桥是PHP-DI / Slim-Bridge

不幸的是,似乎Laravel的数据库事件处理机制严重依赖Laravel的容器实现。 看完这篇很棒的文章后 ,我设法使事件按预期进行。

我设置了一个\\Illuminate\\Container\\Container实例,并将其添加到我的应用程序容器( $container )中并使用了它。 Laravel容器的此实例将仅用于处理事件。 现在,我可以设置\\Illuminate\\Events\\Dispatcher的实例,并通过设置Manager实例进行注册:

$container['laravel-container'] = function ($c){
    return new \Illuminate\Container\Container;
};

$container['database-event-dispatcher'] = function ($c) {
    return new \Illuminate\Events\Dispatcher($c['laravel-container']);
};

$capsule = new \Illuminate\Database\Capsule\Manager();
$capsule->addConnection($container['settings']['db']);
// Pass event dispatcher instance from application container
$capsule->setEventDispatcher($container['database-event-dispatcher']);
$capsule->setAsGlobal();
// Now that we're using events it is important to call $capsule->bootEloquent();
$capsule->bootEloquent();

在创建观察者的新实例时,我们可以传递应用程序$container ,或仅传递观察者中所需的对象。

因此,假设这是我们的SaleObserver类:

class SaleObserver {

    protected $mail;

    public function __construct(MailerInterface $mail){
        $this->mail = $mail;
    }

    public function updating(Sale $sale){
        // Send Mail logic
    }

}

我们应该给它邮件实例:

$container ['mailer'] = function ($c) {
    // set up and return a MailerInterface
};

Sale::observe(new SaleObserver($container['mailer']));

可以将Connection对象与一个空的Laravel容器一起使用,如下所示:

use Illuminate\Database\Connection;
use Illuminate\Database\Connectors\ConnectionFactory;
use Psr\Container\ContainerInterface as Container;

$container[Connection::class] = function (Container $container) {
    $settings = $container->get('settings');
    $config = [
        'driver' => 'mysql',
        'host' => $settings['db']['host'],
        'database' => $settings['db']['database'],
        'username' => $settings['db']['username'],
        'password' => $settings['db']['password'],
        'charset' => $settings['db']['charset'],
        'collation' => $settings['db']['collation'],
        'prefix' => '',
    ];

    $factory = new ConnectionFactory(new \Illuminate\Container\Container());
    $connection = $factory->make($config);

    // Disable the query log to prevent memory issues
    $connection->disableQueryLog();

    return $connection;
};

暂无
暂无

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

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