使用Symfony的服务容器

时间:2015-08-29 14:26:14

标签: php symfony dependency-injection

使用C#,ASP.NET MVC和Autofac之类的东西,我可以创建一个接口IProductService并将其绑定到具体的实现类ProductService,其代码如下所示(其中builder是Autofac.ContainerBuilder):

builder.RegisterType<ProductService>().As<IProductService>();

然后在我的控制器中,我可以创建一个如下所示的构造函数:

using System.Web.Mvc;

namespace SomeNamespace
{
    public class HomeController : Controller
    {
        private IProductService _productService;

        public HomeController(IProductService productService)
        {
            this._productService = productService;
        }
    }
}

使用反射,Autofac能够弄清楚我喜欢注入我的构造函数的IProductService实现,并提供我之前注册的类型作为具体实现类型,解决{{1}中的依赖关系为了创建一个供控制器使用的实例,必要时使用类。

我想使用Symfony实现类似的功能。我目前的理解是,我可以通过以下方式使用Symfony的服务:

ProductService

然后使用这样的控制器:

services:
    product_repository:
        class: App\WebBundle\Repository\ProductRepository
    product_service:
        class: App\WebBundle\Service\ProductService
        arguments: ["@product_repository"]
    home_controller:
        class: App\WebBundle\Controller\HomeController
        arguments: ["@product_service"]

这很有效,但它远非理想,因为我现在不仅在构造函数中提供了接口类型提示(已经明确了我要注入的服务),我还要弄清楚服务命名并在配置文件中为我想要使用服务的每个类提供它们。

我能看到的另一个选择是使用namespace App\WebBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; public class HomeController extends Controller { private $productService; public function __construct(IProductService $productService) { $this->productService = $productService; } } 上的get函数,如下所示:

Symfony\Bundle\FrameworkBundle\Controller\Controller

这种方法很有效,除了我现在完全依赖Symfony的服务容器(将来很难转移到另一个框架),我的IDE不知道namespace App\WebBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; public class HomeController extends Controller { private $productService; public function __construct() { $this->productService = $this->get("product_service"); } } 是什么类型,所以我也失去了自动完成功能。对于服务来自的其他开发人员来说,这也是不明显的,我必须反复参考配置文件,找出注册了哪个类的ID为&#34; product_service&#34; (我无法使用我的IDE导航工具跳转到界面声明或查找实现界面的所有类。)

我的理解是Laravel的Illuminate Container组件提供了我想要实现的功能(使用反射来确定构造函数/方法中暗示了哪种类型,并使用由提供的绑定来解析依赖关系。开发人员)但我不确定是否可以使用Symfony轻松设置。有什么办法可以在使用Symfony的同时实现这个功能(也许我可以听$this->productService并在那里做事)?

2 个答案:

答案 0 :(得分:1)

KévinDunglas开设了一个PR添加服务自动装配,并且自2.8版开始已经集成到Symfony中:https://github.com/symfony/symfony/pull/15613

要实现问题中列出的目标,services.yml文件应如下所示:

services:
    product_repository:
        class: App\WebBundle\Repository\ProductRepository
    product_service:
        class: App\WebBundle\Service\ProductService
        autowire: true
    home_controller:
        class: App\WebBundle\Controller\HomeController
        autowire: true

注册了product_repository服务,以便Symfony依赖注入组件知道至少一个实现IProductRepository的具体类。其他服务上的autowire属性将确保构造函数中的依赖项被正确注入。

可提供进一步的文件here

答案 1 :(得分:0)

编辑:PR现已合并。查看Symfony doc:http://symfony.com/doc/current/components/dependency_injection/autowiring.html

Symfony依赖注入组件当前不支持自动装配。然而,我已经开设了一个PR添加该功能,如果获得足够的积极反馈,它将被集成到Symfony 2.8中:https://github.com/symfony/symfony/pull/15613