DependencyInjection组件

编辑该页面

警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.4,不再维护。

这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。

DependencyInjection组件

在前面的章节中,我们清空了单纯形\框架类通过扩展HttpKernel类同名的组件。看到这个空类,您可能会将一些代码从前端控制器:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27
/ / example.com/src/Simplex/Framework.php名称空间单纯形;使用欧宝娱乐app下载地址\组件\EventDispatcher\EventDispatcher;使用欧宝娱乐app下载地址\组件\HttpFoundation;使用欧宝娱乐app下载地址\组件\HttpFoundation\RequestStack;使用欧宝娱乐app下载地址\组件\HttpKernel;使用欧宝娱乐app下载地址\组件\路由;框架扩展HttpKernel\HttpKernel{公共函数__construct(美元路线){美元上下文=路由\ RequestContext ();美元匹配器=路由\匹配器\ UrlMatcher (美元路线,美元上下文);美元requestStack=RequestStack ();美元controllerResolver=HttpKernel \控制器\ ControllerResolver ();美元argumentResolver=HttpKernel \控制器\ ArgumentResolver ();美元调度程序=EventDispatcher ();美元调度程序- >addSubscriber (HttpKernel \ EventListener \ RouterListener (美元匹配器,美元requestStack));美元调度程序- >addSubscriber (HttpKernel \ EventListener \ ResponseListener (“utf - 8”));::__construct (美元调度程序,美元controllerResolver,美元requestStack,美元argumentResolver);}}

前端控制器代码将变得更加简洁:

1 2 3 4 5 6 7 8 9 10 11
/ / example.com/web/front.phprequire_once__DIR__“/ . . /供应商/ autoload.php”;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;美元请求=请求::createFromGlobals ();美元路线=包括__DIR__“/ . . / src / app.php”;美元框架=单纯形\框架(美元路线);美元框架- >处理(美元请求)- >send ();

有一个简洁的前端控制器允许你有几个单个应用程序的前端控制器。为什么会有用吗?允许有不同配置开发环境和生产实例。在开发环境中,您可能想要开启了错误报告和错误显示在浏览器中,以缓解调试:

1 2
报错(“display_errors”,1);error_reporting (1);

…但你肯定不会希望同样的配置在生产环境。有两个不同的前端控制器给了你机会为他们每个人有一个稍微不同的配置。

所以,把代码从前端控制器框架类使我们的框架更可配置,但同时,它介绍了很多问题:

  • 我们不能自定义侦听器注册了的dispatcher无法外框架类(一个解决方案可能是添加的框架::getEventDispatcher ()方法);
  • 我们已经失去了我们之前的灵活性;你不能改变的实现UrlMatcherControllerResolver了;
  • 与前面的点,我们不能测试框架没有那么多精力了,因为它是不可能模拟内部对象;
  • 我们不能改变传递的字符集ResponseListener了(一个解决方案可以通过它作为构造函数参数)。

前面的代码没有表现出同样的问题,因为我们使用依赖注入;所有依赖项注入他们的对象构造函数(例如,事件调度程序被注入这个框架,这样我们有完全控制它的创建和配置)。

这是否意味着我们需要之间做出选择的灵活性,定制,易于测试和不相同的代码复制并粘贴到每个应用程序前端控制器吗?如您所料,有一个解决方案。我们可以解决所有这些问题,一些通过使用Symfony的依赖注入容器:欧宝娱乐app下载地址

1
美元作曲家需要symfony /依赖项欧宝娱乐app下载地址注入

创建一个新文件依赖注入容器的配置:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/ / example.com/src/container.php使用单纯形\框架;使用欧宝娱乐app下载地址\组件\DependencyInjection;使用欧宝娱乐app下载地址\组件\DependencyInjection\参考;使用欧宝娱乐app下载地址\组件\EventDispatcher;使用欧宝娱乐app下载地址\组件\HttpFoundation;使用欧宝娱乐app下载地址\组件\HttpKernel;使用欧宝娱乐app下载地址\组件\路由;美元containerBuilder=DependencyInjection \ ContainerBuilder ();美元containerBuilder- >注册(“背景”、路由\ RequestContext::类);美元containerBuilder- >注册(“匹配器”、路由\匹配器\ UrlMatcher::类)- >setArguments ([美元路线,引用(“背景”)));美元containerBuilder- >注册(“request_stack”,HttpFoundation \ RequestStack::类);美元containerBuilder- >注册(“controller_resolver”控制器,HttpKernel \ \ ControllerResolver::类);美元containerBuilder- >注册(“argument_resolver”控制器,HttpKernel \ \ ArgumentResolver::类);美元containerBuilder- >注册(“listener.router”,HttpKernel \ EventListener \ RouterListener::类)- >setArguments ([引用(“匹配器”),引用(“request_stack”)));美元containerBuilder- >注册(“listener.response”,HttpKernel \ EventListener \ ResponseListener::类)- >setArguments ([“utf - 8”]);美元containerBuilder- >注册(“listener.exception”,HttpKernel \ EventListener \ ExceptionListener::类)- >setArguments ([“日历\控制器\ ErrorController:: exceptionAction”]);美元containerBuilder- >注册(“调度”,EventDispatcher \ EventDispatcher::类)- >addMethodCall (“addSubscriber”,(引用(“listener.router”)))- >addMethodCall (“addSubscriber”,(引用(“listener.response”)))- >addMethodCall (“addSubscriber”,(引用(“listener.exception”)));美元containerBuilder- >注册(“框架”,框架::类)- >setArguments ([引用(“调度”),引用(“controller_resolver”),引用(“request_stack”),引用(“argument_resolver”)));返回美元containerBuilder;

这个文件的目的是来配置你的对象及其依赖项。在此配置步骤没有实例化。这纯粹是一个静态的描述你需要操作的对象以及如何创建它们。对象将被创建按需访问它们时从容器或容器需要创建其他对象。

例如,创建路由器侦听器,我们告诉Symfony的类名欧宝娱乐app下载地址欧宝娱乐app下载地址\组件\ HttpKernel\ EventListener\ RouterListener,它的构造函数接受一个匹配器对象(新的参考(“匹配器”))。正如你所看到的,每个对象引用的是一个名字,一个字符串,惟一地标识每个对象。这个名字可以让我们得到一个对象和引用其他对象定义。

请注意

默认情况下,每次你得到一个对象从容器中,它将返回相同的实例。这是因为一个容器管理你的“全球”对象。

前端控制器现在只有将一切都结合在一起:

1 2 3 4 5 6 7 8 9 10 11 12 13
/ / example.com/web/front.phprequire_once__DIR__“/ . . /供应商/ autoload.php”;使用欧宝娱乐app下载地址\组件\HttpFoundation\请求;美元路线=包括__DIR__“/ . . / src / app.php”;美元容器=包括__DIR__“/ . . / src / container.php”;美元请求=请求::createFromGlobals ();美元响应=美元容器- >get (“框架”)- >处理(美元请求);美元响应- >send ();

现在创建的所有对象的依赖注入容器,框架代码应该前面的简单版本:

1 2 3 4 5 6 7 8
/ / example.com/src/Simplex/Framework.php名称空间单纯形;使用欧宝娱乐app下载地址\组件\HttpKernel\HttpKernel;框架扩展HttpKernel{}

请注意

如果你想要一个光选择你的容器,考虑丘疹,一个简单的依赖注入容器在大约60行PHP代码。

现在,这里是如何注册自定义侦听器前端控制器:

1 2 3 4 5 6 7
/ /……使用单纯形\StringResponseListener;美元容器- >注册(“listener.string_response”,StringResponseListener::类);美元容器- >getDefinition (“调度”)- >addMethodCall (“addSubscriber”,(引用(“listener.string_response”)));

在描述对象,依赖注入容器也可以通过参数配置。让我们创建一个定义了是否我们在调试模式下:

1 2 3
美元容器- >setParameter (“调试”,真正的);回声美元容器- >getParameter (“调试”);

这些参数可以定义对象定义时使用。让我们使字符集可配置:

1 2 3 4
/ /……美元容器- >注册(“listener.response”,HttpKernel \ EventListener \ ResponseListener::类)- >setArguments ([“%字符集%”]);

这种变化后,必须设置字符集使用前响应侦听器对象:

1
美元容器- >setParameter (“字符集”,“utf - 8”);

而不是依靠公约定义的路线美元的路线变量,又让我们使用一个参数:

1 2 3 4
/ /……美元容器- >注册(“匹配器”、路由\匹配器\ UrlMatcher::类)- >setArguments ([“%路线%”,引用(“背景”)));

和相关的前端控制器的变化:

1
美元容器- >setParameter (“路线”,包括__DIR__“/ . . / src / app.php”);

我们几乎没有触及表面的你能做什么容器:类名作为参数,覆盖现有的对象定义,从共享服务支持倾销一个集装箱一个简单的PHP类,等等。Symf欧宝娱乐app下载地址ony的依赖注入容器非常强大,可以管理任何类型的PHP类。

不要对我大喊大叫,如果你不想使用框架的依赖注入容器。如果你不喜欢它,不使用它。这是你的框架,而不是我的。

这是这本书的最后一章(已经)创建一个框架在Symfony的组件。欧宝娱乐app下载地址我知道,很多话题没有覆盖的细节,但希望它能给你足够的信息开始自己并更好地理解内部Symfony框架是如何工作的。欧宝娱乐app下载地址

玩得开心!

这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。