1

現在、相互に参照するdoctrine2エンティティがある場合、 ZF2モジュールをあるプロジェクトから別のプロジェクトにコピー可能に保つための良い方法は何でしょうか。

私の現在の状況は次のようなものですUser。このユーザーが話すすべての言語にアクセスできるようにしたいエンティティがあります。

もちろん、他の目的にも使用したいのでLanguage、モジュールのコンポーネントではありません。Authentication

namespace Authentication\Entity;

class User {
    public function getSpokenLanguages();
}

と:

namespace Application\Entity;

class Language {
    public function getUsersWhoSpeakThisLanguage();
}

Authentication問題は、モジュールをプロジェクト固有のモジュールから完全に独立させたいということですApplication

Applicationこれらの関係をエンティティから除外したり、モジュールから注入したりするための良い方法はありますか?たぶんUserServiceApplicationモジュール内で)Language[]特定の言語を教えてくれるのUserもいい考えですか?私はそれをこのように呼ぶことができます:

$userService->getUsersLanguages($user);

特にインジェクションはZF2ソリューションかもしれないと思いますが、そのようなDoctrine2エンティティを別のモジュールからどのように拡張できるかわかりません。

4

1 に答える 1

1

ZF2に固有の問題よりも、意味論的な問題について話していると思います。あなたの質問を読んで、私はあなたの言語がファクトリと DI で簡単に促進できる管理されたレイヤーになると思います - 幸運なことに、ZF2 にはすべての適切なツールがあります。ソリューションの潜在的なドラフトとして、次のようなものを検討してください。

LanguageAbstractFactoryを作成します。

namespace Your\Namespace;

use Zend\ServiceManager\AbstractFactoryInterface,
    Zend\ServiceManager\ServiceLocatorInterface;

class LanguageAbstractFactory implements AbstractFactoryInterface
{
    /**
     * Determine if we can create a service with name
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @param                         $name
     * @param                         $requestedName
     * @return bool
     */
    public function canCreateServiceWithName( ServiceLocatorInterface $serviceLocator, $name, $requestedName )
    {
        return stristr( $requestedName, 'Namespace\Language' ) !== false;
    }


    public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
    {
        $filter = new $requestedName();
        $filter->setServiceLocator( $locator );
        return $filter;
    }

}

次に、 ServiceLocatorAwareInterfaceを実装する Language のサブクラスとして、同じ名前空間に言語を作成します(後でデータベースにアクセスできるようにするためなど)。上記のファクトリのコードは、サービス ロケーターを挿入します (ここで、言語アーキテクチャを満たすために他の利点を挿入するように微調整します)。

namespace Your\Namespace;

use Zend\ServiceManager\ServiceLocatorAwareInterface,
    Zend\ServiceManager\ServiceLocatorInterface;


class Language implements ServiceLocatorAwareInterface
{

    protected $serviceLocator;


    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }

    // ... other things your factory knows, that this class may not go here
}

言語の実装は次のようになります。

namespace Your\Namespace\Language;

class English extends \Your\Namespace\Language
{

    public function getUsersWhoSpeakThisLanguage()
    {
        $sm = $this->getServiceManager();
        // get your entities or w/e using the SM
    }
}

getServiceConfig でモジュールの Module.php を微調整して、ファクトリに接続します。

public function getServiceConfig() { return array(

        'abstract_factories' => array(
            // this one generates all of the mass email filters
            'Your\Namespace\LanguageAbstractFactory',
        ),

    );
}

これにより、サービス マネージャーを使用して、サービスを認識する言語を非常に簡単に取得できるようになります。たとえば、サービス対応クラスから:

$sm->getServiceManager()->get( '\Your\Namespace\Language\English' );

構成により、ファクトリが要求を満たすことができるため、ファクトリは、非常に移植性の高い方法で、ビルドしたロジックを使用して英語のインスタンスを自動構成します。

これはファクトリの入門書のようなものです。サービスがユーザー クラスと対話するために使用できるインターフェイス クラスを設定すると、ユーザーから言語サービスへの制御を反転できます。言語サービスが使用できるクラスを含む LanguageAware (たとえば) を User に実装させるには、数ステップ先にする必要があります。

お役に立てれば。この猫の皮を剥ぐには、おそらく 15 通りの方法があります。このアプローチは、「フィルタリング」データなど、同様の問題を解決するために私が使用したものです。フィルターは、情報をフィルター処理でき、情報はフィルターによってフィルター処理できます。

幸運を!

于 2013-02-08T04:27:42.373 に答える