依赖注入容器:单个类的多个实例

时间:2016-01-04 01:29:15

标签: php dependency-injection

我刚刚开始使用依赖注入容器,我遇到的问题使我的代码变得混乱。让我们举一个例子:我有一个简单的Container类来管理多个服务,一个服务可以被标记为"共享,因此它只能创建一个单独的实例。

因此,例如,我将制作一个简单的(它不是我实际使用的那个)依赖注入容器,让我们说,一个User类,我会这样做:

class Container
{
    protected $parameters;

    public function set($index, $value)
    {
        $this->parameters[$index] = $value;
    }

    public function getUser()
    {
        return new User($this->paramaters['id'], $this->parameters['nickname']);
    }
}

$container = new Container();
$container->set('id', 1);
$container->set('nickname', 'Bob');
$container->getUser();

这很好用。但现在,这是另一个案例:让我们说现在,我想要一个Post类,而不是User类,对于每个帖子,我需要在构造函数中设置它们的标题,文本和日期,以及每个帖子都不应该有相同的参数。在这种情况下,依赖注入容器是否适用,如果是这样,我应该如何实现它而不需要乱码?

修改

会问我的用例:

在我的用例中,我实际上使用路由器类来执行此操作,需要使用路由实例。每个实例化的 Route 需要传递两个参数:模式回调。所以每当我要求我的容器创建一个Route实例时,它不应该用于所有 Route s相同的模式和回调,而是一对新的(模式+回调)。我该怎么办?

1 个答案:

答案 0 :(得分:1)

您的目标是创建一个共享抽象,可以将其注入到依赖于其数据的代码中。您可以采取两种方法,我认为您已经将这两种方法混合在一起。

  1. 通用依赖注入容器 - 在这种情况下,我们创建一个非常通用的对象,可以存储和检索其他对象。这里有一个例子:

    <?php
    
    class Container
    {
        protected $dependencies = array();
    
        public function get($key)
        {
            return isset($this->dependencies[$key]) ? $this->dependencies[$key] : null;
        }
    
        public function register($key, $value)
        {
            $this->dependencies[$key] = $value;
        }
    }
    

    然后您可以像这样使用容器:

    $container = new Container();
    $container->register('user', new User(1, 'Bob'));
    $container->register('somethingElse', new SomethingElse(42));
    

    然后您可以将$container传递给另一个函数,方法或对象,您可以在其中执行:

    $user = $container->get('user');
    

    您可以使用许多开源容器,例如PimplePHP-DI

  2. 特定于域的共享抽象 - 另一种方法是制作特定的共享抽象,例如,在您的情况下,可能是UserPost

    <?php
    
    class UserPost
    {
        protected $user;
        protected $post;
    
        public function __construct(User $user, Post $post)
        {
            $this->user = $user;
            $this->post = $post;
        }
    
        public function getUser()
        {
            return $this->user;
        }
    
        public function getPost()
        {
            return $this->post;
        }
    }
    

    然后,您只需注入UserPost并致电$userPost->getUser() / $userPost->getPost()即可。这里的第二种方法基本上就像想要传递的数据项组合的名称一样简单。我更喜欢这种方法,因为它使代码更具可读性,但这是一个观点问题。我更喜欢让我的类名对应于&#34;我认为这个对象是&#34;用简单的英语。在我看来,这也与核心-OO抽象原则更紧密地对齐。但是,选项1中的通用容器是许多人成功使用的方法。