在我的Symfony项目中,我将有很多具有相似依赖关系的类(但是,这些类之间并不直接相关)。例如,其中大多数都需要访问EventBus
。
在其他框架中,我可以为该类指定一个接口,例如:
interface EventBusAwareInterface
{
public setEventBus(EventBus $bus);
public getEventBus() : EventBus
}
然后配置DI容器以识别实现此接口的此类对象,并使用适当的参数调用其setEventBus()
方法。
我想知道Symfony4中是否有一种方法可以做到这一点。
答案 0 :(得分:0)
是的,甚至更简单的事情也是可能的。但是,我不鼓励过度使用它,因为它会很快引入方法名称冲突之类的内容并降低代码的可读性。
也就是说,Symfony
引入了以3.3
开头的服务自动装配概念(我认为),该概念可用于通过零配置进行依赖注入。在PHP
中,接口不能包含实现,但可以包含特征。因此,您可以执行以下操作:
trait FooTraitHandler
{
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
然后:
class RealService
{
use FooTraitHandler;
public function multiply($a, $b)
{
$this->logger->log(LogLevel::ALERT, "Doing some basic math!");
return $a * $b;
}
}
最后,例如,您的控制器可以注入此RealService
服务并照常使用multiply
方法。
所以,有几件事值得一提:
如果两个特性插入了一个具有相同名称的方法,则如果未明确解决冲突,则会产生致命错误。要解决同一类中使用的特征之间的命名冲突,需要使用代替运算符来选择确切的一种冲突方法。
但是,我认为这样做会大大降低代码的可读性。
希望这对您有帮助...
答案 1 :(得分:0)
我的原始评论不正确。您可以使用@inject,但似乎需要附加的jms捆绑包。本来可以宣誓支持该容器的容器,但我想不是。
但是,autowire支持@required annotation似乎可以解决问题。
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
trait RouterTrait
{
/** @var RouterInterface */
protected $router;
/**
* @param RouterInterface $router
* @required
*/
public function setRouter(RouterInterface $router)
{
$this->router = $router;
}
// Copied directly from Symfony ControllerTrait
protected function generateUrl(
string $route,
array $parameters = array(),
int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string
{
return $this->router->generate($route, $parameters, $referenceType);
}
protected function redirect($url, $status = 302) : RedirectResponse
{
return new RedirectResponse($url, $status);
}
protected function redirectToRoute($route, array $parameters = array(), $status = 302) : RedirectResponse
{
return $this->redirect($this->generateUrl($route, $parameters), $status);
}
}
现在,任何使用RouterTrait的自动接线服务都将自动注入路由器。
答案 2 :(得分:0)
您可以像这样在_instanceof
中使用services.yaml
指令:
services:
_instanceof:
App\EventBusAwareInterface:
calls:
- method: setEventBus
arguments:
- '@event.bus.service'