【问题标题】:Request based dependency in Symfony2Symfony2 中基于请求的依赖
【发布时间】:2014-05-27 16:49:01
【问题描述】:

我正在开发一个多租户应用程序。租户在请求侦听器中解析,看起来或多或少类似于以下内容:

/**
 * @Service
 * @Tag(name="kernel.event_listener", attributes={"event": "kernel.request", "method": "onRequest"})
 */
class TenantResolverListener extends ContainerAware
{
    public function onRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();

        // some magic stuff to detect tenant...

        $tenant = new Tenant($request->getHost());
        $this->container->set('tenant', $tenant);
    }
}

为了在我的应用程序的任何位置轻松访问租户配置,我想到了将租户注册为依赖项容器中的依赖项的想法。 这里的问题是,“租户依赖”在编译时是未知的,我不能将它直接注入到其他服务中。 (我必须注入容器并通过容器($this->container->get('tenant'))访问租户配置)。

我认为这根本不是最好的解决方案,但我不太确定如何解决这个问题。我的想法是:

  1. 注册一个默认租户,稍后将在 TenantResolver 中覆盖该租户。
  2. 更早地在任何地方检测当前租户,但在哪里/如何检测?
  3. 不要将租户配置放入容器中
    1. 并将配置包装在自己的服务中,该服务定位当前租户并返回配置。 ($tenantResolver->getConfig())。
    2. 和...?

如果有人有这方面的经验,很乐意给我一些提示。

谢谢!

【问题讨论】:

    标签: symfony dependency-injection multi-tenant


    【解决方案1】:

    让你自己成为一个 TenantFactory 服务,然后让你的租户服务使用它。

    tenant_factory:
        class:  MyProjectBundle\Entity\TenantFactory
    
    tenant:
        class:  MyProjectBundle\Entity\Tenant # Not used but still needed
        factory_service: '@tenant_factory'
        factory_method: get # The container will call $tenantFactory->get() when $tenant is needed.
    
    // Request
    $tenant = new Tenant($request->getHost());
    $tenantFactory = $this->container->get('tenant_factory');
    $tenantFactory->set($tenant);
    
    class TenantFactory
    {
        protected $tenant;
        public function set($tenant) { $this->tenant = $tenant; }
        public function get()        { return $this->tenant; }
    }
    
    // Controller
    $tenant = $this->container->get('tenant');
    

    您必须确保在调用租户相关服务之前触发您的侦听器,但这应该不是问题。

    当然,TenantFactory 并不是真正的工厂,但你明白了。你实际上可以把它变成一个真正的工厂(或存储库),然后让你的请求监听器注入主机名。

    ================================================ ===============

    更新:发布答案几天后,我正在阅读参考书(总是很危险)并且遇到了合成服务的概念。 http://symfony.com/doc/current/components/dependency_injection/advanced.html

    不需要租户工厂。合成服务期望通过 set 添加对象。

    # services.yml
    tenant:
      synthetic: true
    
    // Listener
    $tenant = new Tenant($request->getHost());
    $this->container->set('tenant', $tenant);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 2019-11-05
      • 1970-01-01
      相关资源
      最近更新 更多