在Symfony应用程序中检索当前用户,同时尊重LoD



我在理解Demeter定律在Symfony的DI系统的某些情况下应该如何应用时遇到了一些问题。

我有一些工厂需要访问应用程序中的当前登录用户。要做到这一点,我需要@security.token_storage将其作为构造函数参数注入。

但在我的工厂中,要访问用户,我需要执行以下操作:$tokenStorage->getToken((->getUser((,最糟糕的是,如果我想访问用户的某些属性,我需要更深入一层。

根据德米特定律,你将如何解决这个问题?

这是我的代码示例:

class SomeFactory
{
/**
* @var User
*/
private $currentUser;
/**
* @param TokenStorageInterface $tokenStorage
*/
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->currentUser = $this->setCurrentUser($tokenStorage);
}
/**
* @param TokenStorageInterface $tokenStorage
*/
protected function setCurrentUser(TokenStorageInterface $tokenStorage)
{
if ($tokenStorage->getToken()
&& $tokenStorage->getToken()->getUser()
&& in_array('ADMIN_ROLE', $tokenStorage->getToken()->getUser()->getRoles())
) {
$this->currentUser = $tokenStorage->getToken()->getUser();
}
}
}

我希望我是清楚的。

非常感谢:(

在DI工厂中,会话似乎尚未初始化,这使得当前用户令牌此时不可用。

我做了什么让它工作:

  1. kernel.event:注册一个新的事件侦听器

    services:
    before_request_listener:
    class: AppEventListenerMyRequestListener
    tags:
    -
    name: kernel.event_listener
    event: kernel.request
    method: onKernelRequest
    
  2. MyRequestListener中,我添加了我的服务作为依赖项(它调用工厂(,并提供了数据不完整的服务。我还需要Security:

    public function __construct(SymfonyComponentSecurityCoreSecurity $security, MyService $service)
    {
    $this->security = $security;
    $this->service = $service;
    }
    
  3. 现在,在MyRequestListener::onKernelRequest中,我可以访问用户的数据并添加/更改服务的不完整属性。

    public function onKernelRequest(): void
    {
    if ($user = $this->security->getUser()) {
    $this->service->whatever = $user->whatever;
    }
    }
    

因为Symfony使用相同的MyService实例,所以这些修改将在所有进一步的服务中可用。

但请记住,当不存在活动用户会话时(例如,因为没有用户登录,或在CLI上(,您的服务也需要处理不完整的数据。

最新更新