symfony 中非共享服务的目的是什么?

Whats the purpose of non shared services in symfony?

我明白,如果我使用非共享服务,我每次请求该服务时都会获得新的实例。这将允许我在此类服务中安全地使用 class 属性,如果我在共享服务上这样做是不明智的——这有点类似于并发问题。

但是,非共享服务相对于普通旧 php 对象的优势是什么?

我只能想到开箱即用地获取服务对象内部的 DI 容器访问权限,但这不是什么大问题,因为我可以将我需要的内容传递给构造函数或 POPO 的 setter。

我是不是漏掉了什么?

就我个人而言,归结为 方便。是的,您可以使用简单的对象获得几乎相同的功能。但特别是在需要大量依赖项的情况下,在您需要的每个实例上传递所有依赖项可能会有点麻烦。

只定义一次具有所需所有依赖项的服务,然后根据需要简单地传递它会更容易。在您需要非共享服务的地方,您只传递这个单一服务,而不是创建对象实例所需的 10 个其他依赖项。

我猜 YML 中使用非自动装配的例子是:

services:
    App\NonSharedService:
        autowire: false
        shared: false
        arguments:
            - '@dependency1'
            - '@dependency2'
            ...
            - '@dependency15'

    App\RandomService1:
        autowire: false
        arguments:
            - '@App\NonSharedService'

    App\RandomService2:
        autowire: false
        arguments:
            - '@App\NonSharedService'

现在如果在内部创建 PHP 对象,您需要将所有依赖项传递给 App\RandomService#:

services:
    App\RandomService1:
        autowire: false
        arguments:
            - '@dependency1'
            - '@dependency2'
            ...
            - '@dependency15'

    App\RandomService2:
        autowire: false
        arguments:
            - '@dependency1'
            - '@dependency2'
            ...
            - '@dependency15'

我最近使用非共享服务作为作业服务的 DI 助手 class。

我有一个主管来处理 JobInterface 的所有工作。

每个作业 class 可能有也可能没有自己的依赖项和参数。 所以用老方法做会很麻烦:

$job = new JobA(arg1, arg2); // Argh no DI...
// Do stuff to inject services !!
$pipe->dispatch($job);

所以我做了类似的事情:

services:
...
    App\Job\:
        resource: '../Job/'
        public: true # needed to use $container->get()
        shared: false
$job = $container->get(JobA::class); // Hello DI !
$job->init(arg1, arg2);
$pipe->dispatch($job);

并且我可以在需要时使用 DI 注释的强大功能:

class JobA implements JobInterface
{
    /**
     * @Required
     */
    public function setMyService(MyService $myService)
    {
       ...
    }
}