如何告诉DI容器将某一类型的所有服务注入到另一个服务中?我希望避免将所有这些服务手动注册为参数。
有没有办法让这一切自动化呢?
class A {
/**
* @var ISomeInterface[]
*/
private $implementations;
public function __construct(ISomeInterface ...$implementations)
{
$this->implementations = $implementations;
}
}
interface ISomeInterface {}发布于 2019-01-07 05:37:48
这可能会给你一个大致的概念。它更像是一个伪代码,所以不要复制和粘贴它。Symfony允许您通过ContainerBuilder为您的服务定制DI -在3.4中,我们在*Extension类中这样做。在您的应用程序中,您可以在任何可以访问容器构建器的地方执行此操作。如果您知道需要注入哪些服务,则可以将它们作为参考;如果不知道,则可以遍历定义并找到与您的标准匹配的服务,即所需的接口。
// Symfony 3.4
- `*Extension.php` class, usually found in DependencyInjection folder of a bundle
class BundleExtension extends Extension
{
/**
* @param array $configs
* @param ContainerBuilder $container
* @throws \Exception
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); // Your services
$loader->load('services.yml');
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$implementations = [];
// Get your implementations
$implementations[] = ...;
// You can either loop through config, get them as references (new Reference() ...), compare to interface predicate
$aService = (new Definition(A:class)) // This is the crucial part
->setArgument(0, $implementations);
$container->setDefinition(A::class, $aService);
}
}您可以使用$container->setArguments([/*your arguments*/])向您的服务注入参数。
// Symfony 4.2
// Kernel.php ...
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';
$arguments = [];
$services = [1, '2', 3, 4, 'def', 'abc']; // Your services
foreach ($services as $item) {
if (gettype($item) === 'string') { // Check if they pass your criteria, this is just an example
$arguments[] = $item;
}
}
$aService = (new Definition(A::class, $arguments)); // Service definition
$container->setDefinition(A::class, $aService); // Inject it to a container
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
}https://stackoverflow.com/questions/54065951
复制相似问题