基本的に、特別な名前で「タグ付けされた」いくつかのサービスを記述することで、DIC を使用できます。
このためには、サービスをファイルに定義し (DIC 仕様に従って)、特定の方法でタグ付けする必要があります (この場合、コードは説明のために Sonata Admin Bundle によって取得されます)。
# MyBundle/Resources/config/admin.yml
services:
sonata.admin.tag:
class: YourNS\AdminBundle\Admin\BlogAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: posts, label: "Blog" }
arguments:
- ~
- YourNS\AdminBundle\Entity\Course
- 'SonataAdminBundle:CRUD'
calls:
- [ setTranslationDomain, [YourNSAdminBundle]]
この場合、sonata.admin.tag
タグでタグ付けされたというサービスを定義していますsonata.admin
。タグ名を付け
て、それらを何十個も定義できます。sonata.admin.tag
これが完了したら、 file である「特別な」ファイル ( DependencyInjection
[慣習のために] バンドルのフォルダーに配置する) を作成する必要がありCompilerPass
ます。
CompilerPass ファイルとは何ですか?
コンパイラ パスは、サービス コンテナに登録されている他のサービス定義を操作する機会を提供します。セクション「タグ付きサービスの操作」)。
これはまさにあなたが必要とするものです!
次に、(この特定の例では)でタグ付けされたサービスを(このファイルで)検索する必要がありますsonata.admin
class AddDependencyCallsCompilerPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
$groupDefaults = $admins = $classes = array();
$pool = $container->getDefinition('sonata.admin.pool');
foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $tags) {
foreach ($tags as $attributes) {
$definition = $container->getDefinition($id);
$arguments = $definition->getArguments();
if (strlen($arguments[0]) == 0) {
$definition->replaceArgument(0, $id);
}
if (strlen($arguments[2]) == 0) {
$definition->replaceArgument(2, 'SonataAdminBundle:CRUD');
}
$this->applyConfigurationFromAttribute($definition, $attributes);
$this->applyDefaults($container, $id, $attributes);
$arguments = $definition->getArguments();
$admins[] = $id;
//other logic here
$pool->addMethodCall('setAdminClasses', array($classes));
ここでわかるように、sonata.admin
( $container->findTaggedServiceIds('sonata.admin')
) でタグ付けされたサービスを検索し、それら (この場合は、sonata 管理バンドルに固有のもの)$pool
をContainerBuilder
ここで、CompilerPass をバンドル ファイル (バンドルをアプリケーションに登録する前に作成するファイル) に登録する必要があります。
class SonataAdminBundle extends Bundle
{
/**
* {@inheritDoc}
*/
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new AddDependencyCallsCompilerPass());
}
}
これで、このバンドル専用のある種のサービスが登録されました。サービス工場はより志向的です
Symfony2 のサービス コンテナーは、オブジェクトの作成を制御する強力な方法を提供し、コンストラクターに渡される引数を指定したり、メソッドを呼び出したりパラメーターを設定したりできるようにします。ただし、オブジェクトを作成するために必要なすべてが提供されない場合があります。
または、サービスのインスタンス化の「エントリ ポイント」のように表示します。