为什么不能在CompilerPass中注入记录器服务?

时间:2015-12-07 03:33:11

标签: symfony

我执行此命令

  import math
    import random
    import requests
    import collections
    import string
    import re
    import xml.etree.ElementTree as ET    
    import nltk

def process(url, xpath):
    """
    Downloads a feed url and extracts the results with a variable path
    :param url: string
    :param xpath: string
    :return: list
    """
    contents = requests.get(url)
    root = ET.fromstring(contents.content)
    return [element.text.encode('utf8') if element.text is not None else '' for element in root.findall(xpath)]


  def main(n=50000):

    feeds = [{'url': 'http://www.nyartbeat.com/list/event_type_print_painting.en.xml',
              'xpath': './/'},
             {'url': 'http://feeds.feedburner.com/FriezeMagazineUniversal?format=xml',
              'xpath': './/'}]   

    results = []

    # Loop all the feeds
    for feed in feeds:
        # Append feed results together
        results.extend(process(feed['url'], feed['xpath']))

    # Join all results into a big string
    contents = ",".join(map(str, results))

    # Remove double+ spaces
    contents = re.sub('\s+', ' ', contents)

    # Remove everything that is not a character or whitespace
    contents = re.sub('[^A-Za-z ]+', '', contents)

    words_split = [w.lower() for w in contents.split() if len(w) <=13 ]

    wordlist = [w.lower() for w in nltk.corpus.words.words() ]

    words = [val for val in words_split if val in wordlist]

if __name__ == "__main__":
    main()

显然,有一个名为app/console container:debug | grep logger 的服务:

logger

我使用以下代码注入服务:

 logger                                                             Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.assetic                                             Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.doctrine                                            Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.event                                               Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.php                                                 Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.profiler                                            Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.request                                             Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.router                                              Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.security                                            Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.templating                                          Symfony\Bridge\Monolog\Logger                                                              
 monolog.logger.translation                                         Symfony\Bridge\Monolog\Logger                                                              
 swiftmailer.mailer.default.plugin.messagelogger                    Swift_Plugins_MessageLogger                                                                
 swiftmailer.plugin.messagelogger                                   alias for "swiftmailer.mailer.default.plugin.messagelogger"     

但我收到了这个错误:

  

的Symfony \元器件\ DependencyInjection \异常\ InvalidArgumentException]   服务定义&#34;记录器&#34;不存在。

如果将public function process(ContainerBuilder $container) { $clients= $container->findTaggedServiceIds('socket.client'); foreach ($clients as $id => $tags) { $definition = $container->getDefinition($id); $definition->addArgument($container->getDefinition('logger')); } } 服务更改为logger,那么一切正常,记录器服务会发生什么?

另一个有趣的事情是,尽管上面的方法不起作用,但它在yml中工作,我可以注入monolog.logger.doctrine服务

logger

我必须在代码中注入记录器服务的原因,因为我有几个services: etc.socket.server: class: %etc.socket.server.class% arguments: [@logger, @event_dispatcher, @etc.encoder,@etc.message.client.request] 服务,并且它们在代码中定义。

更新

我可以在appDevDebugProjectContainer.xml中找到记录器服务定义:

socket.client

即使我写了一个编译通道来注入记录器服务,它仍然无法正常工作

 <service id="logger" class="Symfony\Bridge\Monolog\Logger">
      <argument>app</argument>
      <call method="pushHandler">
        <argument type="service" id="monolog.handler.console"/>
      </call>
      <call method="pushHandler">
        <argument type="service" id="monolog.handler.main"/>
      </call>
      <call method="pushHandler">
        <argument type="service" id="monolog.handler.debug"/>
      </call>
 </service>

为什么记录器服务如此特别?

2 个答案:

答案 0 :(得分:3)

尝试在doc中描述的ContainerBuilder类上使用方法findDefinition而不是getDefinition

例如:

使用此:

    $definition->addArgument($container->findDefinition('logger'));

而不是:

    $definition->addArgument($container->getDefinition('logger'));

这两种方法的主要区别在于别名服务的解决方案

  

findDefinition:递归方法“unaliases”返回a   定义实例

源代码here中的进一步参考。

希望这个帮助

答案 1 :(得分:3)

您是否尝试过使用该参考?

$definition->addArgument(new Reference('logger'));

此时此定义可能尚不存在。您永远不会在参数中设置实际定义,而是设置对服务的引用。