首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AuraPHP DI动态类或基于决策的注入

AuraPHP DI动态类或基于决策的注入
EN

Stack Overflow用户
提问于 2016-06-30 20:51:35
回答 1查看 166关注 0票数 1

我是现代依赖注入方法的新手,我正在努力弄清楚如何让方法根据条件选择要使用的类。我打赌我已经摆脱了我的设计结构,但我也不知道如何通过配置在Aura DI中实现这一点。

这是我的Aura Config

代码语言:javascript
复制
<?php
namespace Aura\Cli_Project\_Config;

use Aura\Di\Config;
use Aura\Di\Container;

class Common extends Config {
    public function define(Container $di) {
        // utilities
        $di->set(
            'App\Inventory\Utilities\EmailParser',
            $di->newInstance('App\Inventory\Utilities\PlancakeParser')
        );

        // commands
        $di->params['App\Inventory\Command\IncomingOrder'] = array(
            'stdio' => $di->lazyGet('aura/cli-kernel:stdio'),
            'parser' => $di->get('App\Inventory\Utilities\EmailParser')
        );
    }
    // ...
}

这个类需要使用不同的类,这取决于它找到的“源”。

代码语言:javascript
复制
<?php

namespace App\Inventory\Command;

use Aura\Cli\Stdio;
use App\Inventory\Utilities\EmailParser;
use App\Inventory\Sources\Etsy;
use App\Inventory\Sources\Amazon;
use App\Inventory\Sources\Ebay;

class IncomingOrder {

    public function __construct(
        Stdio $stdio,
        EmailParser $parser) {
        $this->stdio = $stdio;
        $this->parser = $parser;
    }

    public function process() {
        // other code to parse message
        // source is set by determining where it came from
        $source = 'Etsy';

        switch($source) {
            case 'Etsy' :
                // This bit seems really wrong
                $sourceParser = new Etsy\OrderParser();
                break;
            case 'Amazon' :
                $sourceParser = new Amazon\OrderParser();
                break;
            case 'Ebay' :
                $sourceParser = new Ebay\OrderParser();
                break;
            default :
                $sourceParser = null;
        }

        // Do source specific processing
    }
}

是否需要在确定源之后将处理拆分,以便使用该源作为参数初始化一个新类?

我看到在配置中这样做的唯一方法是执行一个懒惰的匿名函数来返回适当的源类,但这也违背了现代设计原则。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-01 14:27:23

我想澄清的是,您不需要像这里的许多di容器那样使用set方法。您可以将代码修改为

代码语言:javascript
复制
<?php
namespace Aura\Cli_Project\_Config;

use Aura\Di\Config;
use Aura\Di\Container;

class Common extends Config 
{
    public function define(Container $di) 
    {
        // commands
        $di->params['App\Inventory\Command\IncomingOrder'] = array(
            'stdio' => $di->lazyGet('aura/cli-kernel:stdio'),
            'parser' => $di->lazyNew('App\Inventory\Utilities\EmailParser')
        );
    }
    // ...
}

当您想要将同一个对象传递给许多其他对象时,您可以使用set。不要使用newInstance,因为它会在调用相同的对象时创建对象。您可能需要使用lazyNewlazyGet功能。

关于你关于动态决策的问题。这是我的想法,我之前确实遇到过这个问题。但是没有看到我做了什么,iirc,我所做的就是将一个工厂注入到IncomingOrder类中,它可以创建对象。它的好处是,如果您的源解析需要某种类型的依赖,您可以在工厂中使用di。

例:

代码语言:javascript
复制
<?php
namespace Something;

use Aura\Di\Container;

class SourceFactory
{
    public function __construct(Container $di) 
    {   
        $this->di = $di;
    }

    public function newInstance($source)
    {
        if ($di->has($source)) {
            return $di->get($source);
        }
        // or alternatively create with new as done in switch
    }
}

希望这能有所帮助。

谢谢

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38133034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档