Doctrine orm 避免两个模块中实体之间的循环依赖

Doctrine orm 避免两个模块中实体之间的循环依赖,doctrine-orm,zend-framework2,Doctrine Orm,Zend Framework2,我目前想知道,如果我有相互引用的doctrine2实体,有什么好方法可以使ZF2模块从一个项目复制到另一个项目 我目前的情况是这样的:我有一个实体用户,我希望能够访问该用户所说的所有语言 当然,Language不是Authentication模块的一个组件,因为我可能也想将其用于其他目的 名称空间身份验证\实体; 类用户{ 公共函数getSpokenLanguages(); } 以及: 名称空间应用程序\实体; 课堂语言{ 公共函数getUsersWhoSpeakThisLanguage();

我目前想知道,如果我有相互引用的doctrine2实体,有什么好方法可以使ZF2模块从一个项目复制到另一个项目

我目前的情况是这样的:我有一个实体
用户
,我希望能够访问该用户所说的所有语言

当然,
Language
不是
Authentication
模块的一个组件,因为我可能也想将其用于其他目的

名称空间身份验证\实体;
类用户{
公共函数getSpokenLanguages();
}
以及:

名称空间应用程序\实体;
课堂语言{
公共函数getUsersWhoSpeakThisLanguage();
}
问题是,我希望我的
身份验证
模块完全独立于特定于项目的模块
应用程序

有没有一种好方法可以让这些关系远离我的实体,或者从
应用程序
模块中注入它们?也可能是
用户服务
(在
应用程序
模块中)为特定的
用户
提供语言
语言[]
是个好主意?我可以这样称呼它:

$userService->getUsersLanguages($user);

我认为,尤其是注入可能是一个ZF2解决方案,但我不知道如何从另一个模块扩展Doctrine2实体。

我认为您谈论的更多是语义问题,而不是ZF2特有的问题。阅读您的问题,我认为您的语言更像是一个管理层,您可以通过工厂和DI方便地使用它,幸运的是ZF2拥有所有正确的工具。把这样的事情看作是一个解决方案的潜在草案:

创建一个语言抽象工厂

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(为您提供数据库访问权限等等)。上面工厂中的代码注入了服务定位器(这就是您调整它以注入其他优点以满足您的语言体系结构的地方):

语言实现可能如下所示:

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连接工厂:

公共函数getServiceConfig(){ 返回数组(

这使您能够使用service manager非常轻松地获取服务感知语言。例如,从服务感知类:

$sm->getServiceManager()->get( '\Your\Namespace\Language\English' );
由于配置,并且工厂可以满足请求,因此工厂将以非常可移植的方式自动配置English实例,其中包含您构建的任何逻辑

这是一种对工厂的入门——如果你装配了一个服务可以用来与你的用户类对话的接口类,你可以从用户那里转换对语言服务的控制。让你的用户实现LanguageAware(例如),其中包含语言服务可以使用的类,应该需要几步之遥

希望这能有所帮助。大概有15种方法可以剥这只猫的皮;这种方法是我用来解决类似问题的方法,例如“过滤”数据。过滤器可以过滤信息,信息可以通过过滤器过滤


祝你好运!

< P>我认为你所说的语义问题比ZF2所说的要多。阅读你的问题,我认为你的语言变得更像是一个管理层,你可以很容易地与工厂进行交流,幸运的是,ZF2拥有所有正确的工具。 创建一个语言抽象工厂

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(以使您能够访问数据库等)。上面工厂中的代码注入了服务定位器(这就是您调整它以注入其他优点以满足您的语言体系结构的地方):

语言实现可能如下所示:

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连接工厂:

公共函数getServiceConfig(){ 返回数组(

这使您能够使用service manager非常轻松地获取服务感知语言。例如,从服务感知类:

$sm->getServiceManager()->get( '\Your\Namespace\Language\English' );
由于配置,并且工厂可以满足请求,因此工厂将以非常可移植的方式自动配置English实例,其中包含您构建的任何逻辑

这是一种对工厂的入门——如果你装配了一个服务可以用来与你的用户类对话的接口类,你可以从用户那里转换对语言服务的控制。让你的用户实现LanguageAware(例如),其中包含语言服务可以使用的类,应该需要几步之遥

希望这能有所帮助。大概有15种方法可以剥这只猫的皮;这种方法是我用来解决类似问题的方法,例如“过滤”数据。过滤器可以过滤信息,信息可以通过过滤器过滤


祝你好运!

当我从服务定位器调用一种语言的新实例时,我很难理解工厂是如何被调用的。我看不到它的规则。更大的问题是:我看不到它如何帮助我摆脱对用户->应用程序的依赖性。我仍然有一个硬编码的方法
getStuffFromOtherModule()
,不是吗?我想这是因为我还不太习惯使用DI和ServiceLocator。@Aufziehvogel检查当我从服务定位器调用一种语言的新实例时,我很难理解工厂是如何被调用的。我看不到它的规则。更大的问题是:我看不到它如何帮助我进入工厂摆脱用户->应用程序依赖性