2012-01-13 18 views
7

私は様々な種類のページをレンダリングするための簡単なサービスを構築しようとしています。 Strategy patternとして設計されるSymfony2の戦略パターン

$somePageType = new PageType(...); 
$this->get('page.service')->render($somePagetype); 

...:基本的な考え方は次のようなものを持っています。ページタイプはrenderメソッドとのインターフェイスを実装し、page.serviceはそれを呼び出します。問題は、ページ型クラスでDoctrineを使用したいと思うことです。私の選択肢は何ですか?私はこれらのクラスのそれぞれについてサービスを作成することを避けたいと思います。それも可能ですか?サービスなしでコンテナに対応させることは可能ですか?おそらく、将来的には、ページの種類によってはDoctrine以外のものが必要かもしれないので、そのことにも留意する必要があります。

答えて

1

PageTypeは、戦略クラスの例です。その場合、依存関係をpage.serviceで注入することができ、戦略をサービスとして定義する必要はありません。

それぞれの戦略はおそらく異なるオブジェクトに依存するため、私はそれらをContainerAwareにすることができたと思います。ここでは、それは

// This is the page.service class 
class MyPageService { 

    public function render(PageTypeInterface $page_type) { 
     $page_type->setContainer($this->container); 

     // do stuff 
    } 
} 

// This is the type strategy 
class MyStrategyType extends ContainerAware implements PageTypeInterface { 
    // you can access the container after MyPageService has injected it. 
} 

だから、基本的にそれぞれの戦略が ContainerAwareを延長するために行うと page.serviceは、容器を注入する方法を例です。


EDIT

あなたの戦略のすべてが同じサービスに依存している場合は、私が代わりに容器全体のそれらを注入したいです。

class MyPageService { 

    public function render(PageTypeInterface $page_type) { 
     $page_type->setService($this->container->get('my_service')); 

     // do stuff 
    } 
} 
+0

これは、コンテナを周囲に通すのは良いことではありません。彼の目的が教義を必要とするならば、それは教義の目的のためのコンストラクタにパラメータを加えることによってそれを要求すべきです。 – meze

+0

@もちろん、すべての戦略に依存性が異なる場合はどうなりますか?これが唯一の方法でしょう。しかし、私は個人的にすべての戦略を実際にサービスとして定義します。 – gilden

+0

あなたの戦略をどのようにテストしますか? symfonyなしで別のプロジェクトで再利用できますか? – meze

3

サービスは、ここで必要なものです。問題の特定の戦略の依存関係を注入できること。次に、特定の戦略をコントローラに注入します(実行時に戦略を選択するダイナミックレンダラーでもあります)。

ContainerAwareは本当に悪い習慣です。問題のオブジェクトをコンテナ内のサービスのすべてに結合します。したがって、私はそれを避けることを強くお勧めします。

関連する問題