2017-07-19 42 views
0

的名單在多租戶系統,我注入當前用戶角色爲我所有的學說存儲庫,以確保用戶只能看到他們有機會獲得:自動裝配,以減少服務

class SiteRepository extends SecurityAwareRepository 
{ 
    public function createQueryBuilder($alias, $indexBy = null) 
    { 
     $qb = $this->_em->createQueryBuilder() 
         ->select($alias) 
         ->from($this->_entityName, $alias, $indexBy) 
         ->orderBy("$alias.name"); 

     switch ($this->getHighestRole()) { 
      case 'ROLE_PARTNER': 
       $qb 
        ->innerJoin("$alias.BilledTo", 'o') 
        ->innerJoin('o.Users', 'u') 
        ->where('u.id=:user_id') 
        ->setParameter('user_id', $this->getUserId()) 
       ; 
       break; 
      case 'ROLE_CUSTOMER': 
       $qb 
        ->innerJoin("$alias.Organisation", 'o') 
        ->innerJoin('o.Users', 'u') 
        ->where('u.id=:user_id') 
        ->setParameter('user_id', $this->getUserId()) 
       ; 
       break; 
      case 'ROLE_SUPERADMIN': 
       //full access 
       break; 
      default: 
       $qb->where('1=0'); 

     } 
     return $qb; 
    } 

我米目前裝載這些庫爲這樣的服務:

services: 
    invoice_repository: 
     class: AppBundle\Repository\InvoiceRepository 
     factory: ["@doctrine", getRepository] 
     arguments: 
      - "AppBundle:Invoice" 
     calls: 
      - method: setTokenStorage 
      arguments: 
       - "@security.token_storage" 
    site_repository: 
     class: AppBundle\Repository\SiteRepository 
     factory: ["@doctrine", getRepository] 
     arguments: 
      - "AppBundle:Site" 
     calls: 
      - method: setTokenStorage 
      arguments: 
       - "@security.token_storage" 

我可以消除這種重複與自動裝配,如果是如何?

+1

雖然與autowire無關,但實際上可以插入自己的RepositoryFactory類,從而可以爲您注入令牌存儲。消除呼叫部分。 https://stackoverflow.com/questions/44008937/how-can-i-inject-class-inside-custom-repository-symfony-2-7/44070750#44070750使用你自己的工廠在概念上好一點,因爲它允許$ em-> getRepo按預期工作。 – Cerad

+1

避免調用部分的另一種方法是使用父服務。 https://symfony.com/doc/current/service_container/parent_services.html – Cerad

+0

Cerad,我實現了一個自定義倉庫工廠,你可以添加這個作爲我能接受的答案嗎? – jdog

回答

2

直到最近

有一段時間,我用了一個特質和有線的setter注入就像在你的榜樣,這是相當重複的。

然後,我開始使用改進的自動裝配在3.3幫助電線我倉庫像這樣:

services: 
    _defaults: 
     autowire: true 
     autoconfigure: true 
     public: false 

    ...... redacted stuff ...... 

    Entity\PageRepository: 
     public: true 
     factory: ['@doctrine.orm.default_entity_manager', getRepository] 
     arguments: [Entity\Page] 

裏面PageRepository,我用一個特質象下面這樣:

trait AppContextTrait 
{ 
    protected $appContext; 

    /** 
    * @required 
    */ 
    public function setAppContext(AppContext $appContext) 
    { 
     $this->appContext = $appContext; 
    } 

    public function getAppContext(): AppContext 
    { 
     return $this->appContext; 
    } 
} 

@required註解告訴autowirer在類實例化時調用方法。

實際上我的DIC配置很少,一切都完全自動裝配,除了存儲庫。在存儲庫的DIC配置中仍然有很多重複。

但現在,

我讀Magnus Nordlander's blog post about autowiring repositories後,我已經開始建立我的倉庫類似於下面馬格努斯的例子。它避免了封閉的實體管理器問題,並且它可以讓自動裝配處理DIC配置。現在我的DIC配置文件非常纖薄! :)

class UserRepository 
{ 
    private $managerRegistry; 

    public function __construct(\Doctrine\Common\Persistence\ManagerRegistry $managerRegistry) 
    { 
     $this->managerRegistry = $managerRegistry; 
    } 

    public function find($id): ?User 
    { 
     return $this->getManager()->find(User::class, $id); 
    } 

    public function findOneUsingACustomQuery($parameter): ?User 
    { 
     return $this->getManager()->createQueryBuilder() 
      ->from(User::class, 'u') 
      ->where('u.something = :param') 
      ->setParameter('param', $parameter) 
      ->setMaxResults(1) 
      ->getQuery() 
      ->execute() 
      ->getSingleResult(); 
    } 

    protected function getManager(): \Doctrine\ORM\EntityManager 
    { 
     return $this->managerRegistry->getManagerForClass(User::class); 
    } 
} 
+0

這也是一個非常好的答案,我看過那篇文章。但是在這一點上還沒有選擇這個,因爲我不清楚他在公關時碰到了什麼問題。希望瞭解更多 – jdog