支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
在本节,服务的配置文件被称作resources(资源)。这是为了强调一个事实,尽管多数配置资源都是文件形式(如YAML、XML、PHP),Symofny仍然保持极度灵活,配置信息是可以从任何地方加载的(比如从数据库中,甚至从一个外部web service)。
服务容器在构建时要使用一个配置资源(默认是app/config/config.yml
)。所有其他服务配置(包括Symfony核心和第三方bundle的配置),必须从这个文件中被导入进来。这给了你绝对的灵活性来搞定你程序中的服务。
外部服务配置在导入时可以有两种方式。第一种方法,通常用于导入其他资源(译注:一般是把service/routing等配置加载到主配置文件中),通过imports
指令。第二种方法,是使用dependency injection extensions(译注:SF根本核心之DI扩展,直接语义化配置,这部分配置交由用户完成,再经由扩展被bundle取得,程序才能按需运行。此部分非常难,是SF灵魂层面,必须精通容器用法),用于第三方bundle加载配置。继续阅读以了解这两种方法。
现在,你已经替换了你的app.mailer
服务容器定义,直接在服务配置文件中完成(如app/config/services.yml
)。如果你的程序有很多服务,这个文件会非常大且难于维护。为了避免这种情况,你可以分离出你的服务配置到多个服务文件中:
1 2 3 4 5 6 7 8 | # app/config/services/mailer.yml
parameters:
app.mailer.transport: sendmail
services:
app.mailer:
class: AppBundle\Mailer
arguments: ['%app.mailer.transport%'] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!-- app/config/services/mailer.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="app.mailer.transport">sendmail</parameter>
</parameters>
<services>
<service id="app.mailer" class="AppBundle\Mailer">
<argument>%app.mailer.transport%</argument>
</service>
</services>
</container> |
1 2 3 4 5 6 7 8 9 | // app/config/services/mailer.php
use Symfony\Component\DependencyInjection\Definition;
$container->setParameter('app.mailer.transport', 'sendmail');
$container->setDefinition('app.mailer', new Definition(
'AppBundle\Mailer',
array('%app.mailer.transport%')
)); |
定义本身并未改变,只是它的位置发生改变。为了让容器在这个资源的位置来加载定义,在已经加载了资源中使用imports
根键(如app/config/services.yml
或app/config/config.yml
):
1 2 3 | # app/config/services.yml
imports:
- { resource: services/mailer.yml } |
1 2 3 4 5 6 7 8 9 10 11 | <!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<imports>
<import resource="services/mailer.xml"/>
</imports>
</container> |
1 2 | // app/config/services.php
$loader->import('services/mailer.php'); |
resource
键对应的位置,对于文件来说,既可以是相对于当前文件的路径,也可以是绝对路径。
因为parameter参数的解析方式,你不能使用它们来构建“动态导入”路径。这意味着像下面这种配置将不会工作:
1 2 3 | # app/config/config.yml
imports:
- { resource: '%kernel.root_dir%/parameters.yml' } |
1 2 3 4 5 6 7 8 9 10 11 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<imports>
<import resource="%kernel.root_dir%/parameters.yml" />
</imports>
</container> |
1 2 | // app/config/config.php
$loader->import('%kernel.root_dir%/parameters.yml'); |
第三方bundle的容器配置,包括Symfony核心服务,在加载时通常使用另外一种方法,更加灵活,也更加容易在程序中进行配置。
在内部,每个bundle就像你看到的那样来定义它们的服务。但是,这些文件并不使用imports
指令进行导入。这些bundles,使用的是 dependency injection extension 来加载文件。扩展还支持bundle让配置信息能够“动态加载服务”。
看看FrameworkBundle - 这是Symfony框架的核心bundle - 以它为例。在你的程序配置中,有下面这种代码,调用的就是FrameworkBundle的容器扩展:
1 2 3 4 5 | # app/config/config.yml
framework:
secret: xxxxxxxxxx
form: true
# ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
>
<framework:config secret="xxxxxxxxxx">
<framework:form />
<!-- ... -->
</framework>
</container> |
当资源被解析时,容器要寻找一个负责处理framework
指令的扩展。这种扩展,是存放在FrameworkBundle里面,该扩展将被调用,同时FrameworkBundle的相关服务配置也会被加载进来。
framework
指令下面的设置(如form: true
),用于指示扩展应该加载全部与“表单组件”相关的服务。如果表单被禁用,这些服务将不再被加载,表单整合将不可用。
当安装或配置一个bundle时,要参考bunlde文档以明确该bunlde所需之相关服务应如何安装和配置。例程中的核心bundle的配置选项可以在Refernce Guide(参考文档)中找到。
如果你希望在自己的共享bundles中使用dependency injection extension(译注:Symfony的DI扩展,简称Extension。bundle分发时必须要用到),并且提供给用户以友好的配置,看一下 如何在Bundle内加载服务配置这篇文章。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。