Slim Framework中的依赖注入-将容器传递到您自己的类中 [英] Dependency Injection in Slim Framework - passing Container into your own classes

查看:148
本文介绍了Slim Framework中的依赖注入-将容器传递到您自己的类中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经对此线程发表了评论,但是它似乎已经死了,所以我要打开一个新线程:


编辑-我将其添加到为进一步解释该问题而做出的评论之一中:

如果您查看第一应用程序教程"- http://slimframework.com/docs/tutorial/first-app.html -他们正在向容器添加PDO数据库连接.

假设我在一个子目录中有100个单独的类(示例中有一个../classes/目录),并使用spl_autoload_register()将它们自动加载到index.php中.该容器在所有这些类中均不可用.

如果我必须分别传递100次,那么每次使用一个类时,只是为了获得PDO连接(这只是一个示例),那么这会使代码具有很强的重复性,即不是DRY.

解决方案

Slim附带了 Pimple 默认.一些开发人员认为(我倾向于同意),Pimple不是依赖注入容器,而是服务定位器,因为它不能自行解决依赖关系,因此需要注册它们.

Slim 3与实现容器interop接口的任何依赖项管理器配合使用,该PHP -DI有.

选择此软件包.这就是我在我的项目中使用的,而且令人惊奇,因为自动装配 .简单地说,PHP-DI读取类的构造函数并了解需要注入的内容,因此不必像使用Pimple那样注册依赖项.

有时候,我认为(希望?)PHP-DI将取代Pimple作为Slim的默认DI容器,因为它更加先进.

这是您使用Pimple的方法:

<?php
namespace Controllers;

class UsersController
{
    // Inject Container in controller (which is bad, actually)
    public function __construct(ContainerInterface $container)
    {
        // grab instance from container
        $this->repository = $container['userRepository'];
    }

    // Handler of a route
    public function getAllUsers($request, $response)
    {
        $user = $this->repository->getAllUsers();
        return $response->withJson($users);
    }
}

这是与PHP-DI相同的控制器:

<?php
namespace Controllers;

class UsersController
{
    // Declare your dependencies in constructor:
    // PHP-DI will find the classes and inject them automatically
    public function __construct(UserRepository $repository)
    {
        $this->repository = $repository;
    }

    // Handler of a route
    public function getAllUsers($request, $response)
    {
        $user = $this->repository->getAllUsers();
        return $response->withJson($users);
    }
}

问题是,如果我说100堂课,我是否必须通过 (或注入)容器100次?看起来真的,真的 乏味.

如果您使用Slim与PHP-DI捆绑在一起,则可以通过自动装配自动解决问题. :)

I've already commented on this thread but it seems to be dead so I'm opening a new one: Dependency Injection Slim Framework 3

The post above explains how pass Slims Container to a class you've written yourself.

However, the OP has asked if it's possible to get Slim to Dependency Inject ALL their classes.

I'm also interested in knowing if there's a way to do this since it seems to be anything but DRY if you have to pass the container to every class that you want to use it.

As an example, if I want to use one of Slim's functions (such as doing a redirect, in one of my own classes) I cannot use this as per the documentation:

$res->withStatus(302)->withHeader('Location', 'your-new-uri');

Because $res (the response object) is not within the scope of my class, unless I inject/pass it.

The problem with this is, if I have say 100 classes, do I have to pass (or inject) the container 100 times? That seems really, really tedious.

In frameworks like CakePHP you can use the 'AppController' to globally do stuff like this, i.e. define things once, and make it available in ALL your classes. Does Slim not provide this functionality? If not, that's a serious drawback, IMO.


Edit - I'm adding this from one of the comments I've made to try and explain the issue further:

If you look at the First Application Tutorial - http://slimframework.com/docs/tutorial/first-app.html - they are adding a PDO database connection to the container.

Let's say I have 100 separate classes in a sub-directory (the example has a ../classes/ directory) and autoload them in index.php using spl_autoload_register(). The container is NOT available in any of those classes.

If I had to pass something 100 separate times, each time I use one of my classes, just to get a PDO connection (and that's just one example) then that makes the code very repetetive, i.e. not DRY.

解决方案

Slim comes with Pimple by default. Some developers argue (and I tend to agree with them) that Pimple is not a dependency injection container, but a service locator, since it doesn't resolve dependencies on its own, you need to register them.

Slim 3 works with any dependency manager that implements Container interop interface, which PHP-DI does.

Go for this package. This is what I'm using for my projects and it's simply amazing, because of autowiring. To put it simply, PHP-DI reads constructor of the class and understands what needs to be injected, son you don't have to register dependencies as you would with Pimple.

Sometimes I think (hope?) that PHP-DI will replace Pimple as Slim's default DI container, because it's simply more advanced.

Here's how you do with Pimple:

<?php
namespace Controllers;

class UsersController
{
    // Inject Container in controller (which is bad, actually)
    public function __construct(ContainerInterface $container)
    {
        // grab instance from container
        $this->repository = $container['userRepository'];
    }

    // Handler of a route
    public function getAllUsers($request, $response)
    {
        $user = $this->repository->getAllUsers();
        return $response->withJson($users);
    }
}

Here's the same controller with PHP-DI:

<?php
namespace Controllers;

class UsersController
{
    // Declare your dependencies in constructor:
    // PHP-DI will find the classes and inject them automatically
    public function __construct(UserRepository $repository)
    {
        $this->repository = $repository;
    }

    // Handler of a route
    public function getAllUsers($request, $response)
    {
        $user = $this->repository->getAllUsers();
        return $response->withJson($users);
    }
}

The problem with this is, if I have say 100 classes, do I have to pass (or inject) the container 100 times? That seems really, really tedious.

If you use Slim bundled with PHP-DI, the problem is solved autmatically with autowiring. :)

这篇关于Slim Framework中的依赖注入-将容器传递到您自己的类中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆