【问题标题】:Symfony2 Dependency Injection to custom/business classesSymfony2 对自定义/业务类的依赖注入
【发布时间】:2014-11-18 08:37:18
【问题描述】:

我没有在 Google 或 Stackoverflow 上找到类似的问题/解决方案,所以我在这里,需要帮助。 我正在将 PHP 项目从自定义框架移植到 Symfony 框架(v2.5),该框架具有自定义依赖注入(基于类反射)。许多业务逻辑类都注入了属性,我很感兴趣是否有办法在 Symfony 中做类似的事情而不将这些类声明为服务,因为一些类用于临时保存/操作来自 3rd 方端点的内容和我需要它们的不同实例。

更准确地说,有一种方法可以将依赖注入与使用 new 关键字的实例化对象结合使用。因此,如果我需要一个依赖于记录器或验证器的新类,我该如何做这样的事情。

我要解决依赖注入的内容类:


class Content extends SomeObject
{
    private $pictureUrl;
    ...

    public __construct(array $array = null)
    {
        parent::__construct($array);
    }

    public setPicture(...\Picture $picture)
    {
        // what's the best way to inject/enable this into my class
        $errors = $this->get('validator')->validate($picture->getUrl());
        ...
        $this->pictureUrl = $picture->getUrl();
    }

    ...
}

实例化前一个类的类(在这种特殊情况下,这可能是一个服务,但在其他情况下,这是另一个与业务逻辑相关的类):


class EndpointService extends Service
{
    ...

    public fetchContent()
    {
        $dataArray = $this->endpoint->fetch();
        $contentArray = array();

        foreach ($dataArray as $key => $value) {
            $content = new Content(array());
            $content->setPicture($value->picture);
            ...
            $contentArray[$key] = $content;
        }
    }
    ...
}

注意:如果有逻辑/语法错误,请忽略它们,这是我演示问题的示例,与我的代码库相距甚远。

【问题讨论】:

    标签: php symfony dependency-injection


    【解决方案1】:

    在我看来,您的 Content 是一个模型,并且应该在 EndpointService 类中完成验证。

    如果您不想直接将其注入到EndpointService,您可以考虑重构,以便可以将验证器注入到EndpointService 继承自的Service 父类。

    class EndpointService extends Service
    {
        protected $validator;
    
        public __construct(Validator $validator) {
            $this->validator = $validator;
        }
    
        ...
    
        public fetchContent()
        {
            $dataArray = $this->endpoint->fetch();
            $contentArray = array();
    
            foreach ($dataArray as $key => $value) {
                $content = new Content(array());
                $errors = $this->validator->validate($value->picture->getUrl());
                $content->setPicture($value->picture);
                ...
                $contentArray[$key] = $content;
            }
        }
    
        ...
    }
    

    在你的配置中:

    // config.yml
    services:
        app.endpoint_service:
            class: Acme\DemoBundle\External\EndpointService
            arguments: [@validator]
    

    【讨论】:

    • 这是一个有效的观点,谢谢,我会按照你的建议进行。但是如果我仍然想在类似的情况下进行依赖注入怎么办。是否有任何正当理由,即我想在不是服务的商务舱中使用记录器或类似的东西。附:我想为你投票,但我的声誉还不够。编辑:在评论结束前不小心按了回车键。
    • 感谢您的支持;我很感激!回复:注入非服务类...您可以考虑让这些类扩展 [api.symfony.com/2.5/Symfony/Component/DependencyInjection/… Aware)。不确定这是否是最佳做法。是什么阻止您将这些课程变成服务?我不明白他们作为“临时/持有”对象的状态是如何影响这一点的。
    • 并不是所有的类都对应于服务范式,例如光标类(用于内容的分页)就是我的意思,以及一些用于将第 3 方内容获取到客户端的类(类似于实体,但不会被持久化)。我正在寻找解决该项目的方法,因为它相当大并且具有不同类型的依赖注入(基于反射),这与 Symfony 自己的 DI 系统非常不同。正如你所说,我应该重新考虑我的架构,并且我会根据 Symfony 的实践尽可能地重塑它。再次感谢! :)
    【解决方案2】:

    我看到了一种方法,即通过依赖注入将validator 依赖传递给EndpointService。然后你可以将它传递给新的Content

    class EndpointService extends Service
    {
        ...
        public function construct($validator)
        {
            $this->validator = $validator;
        }
    
    
        public fetchContent()
        {
            $dataArray = $this->endpoint->fetch();
            $contentArray = array();
    
            foreach ($dataArray as $key => $value) {
                $content = new Content($this->validator, array());
                $content->setPicture($value->picture);
                ...
                $contentArray[$key] = $content;
            }
        }
        ...
    }
    
    class Content extends SomeObject
    {
        private $pictureUrl;
        ...
    
        public __construct($validator, array $array = null)
        {
            $this->validator = $validator;
    
            parent::__construct($array);
        }
    
        public setPicture(...\Picture $picture)
        {
            // what's the best way to inject/enable this into my class
            $errors = $this->validator->validate($picture->getUrl());
            ...
            $this->pictureUrl = $picture->getUrl();
        }
    
        ...
    }
    

    【讨论】:

    • 是的,但是如果课程不是服务,那我该如何解决这个问题呢? “顶级”类可能是一个服务,但我是否想将 5-10 个依赖项传递给新创建的类以填充它们的依赖项?
    • 定义很多服务然后将这些服务传递给另一个服务是很常见的。 (哟 dawg - 听说你喜欢服务)
    猜你喜欢
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多