2016-10-21 7 views
3

이미이 스레드에 댓글을했지만 그래서 개방하고있어 죽은 것 같다 새 : Dependency Injection Slim Framework 3는 의존성 삽입 (Dependency Injection) - 자신의 클래스로 컨테이너를 통과

게시물은 위의 주 slims를 전달하는 방법을 설명 스스로 작성한 수업에 대한 컨테이너.

그러나 OP는 Slim에서 Dependency Inject ALL 클래스를 가져올 수 있는지 묻습니다.

컨테이너를 클래스로 전달해야 할 경우 DRY가 될 것 같으므로이를 수행하는 방법이 있는지 알고 싶습니다. 모든 클래스를 사용하고 싶습니다. 예를 들어

, 나는이 문서에 따라이 사용할 수 없습니다 (내 자신의 클래스 중 하나에 리디렉션, 을하는 등) 슬림의 기능 중 하나를 사용하려면 :

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

때문에 $res (응답 객체)은 내가 주입/통과하지 않는 한, 내 클래스의 범위 안에 있지 않습니다.

문제는 100 개의 클래스를 말하면 컨테이너를 100 번 (또는 주입해야합니까?) 필요합니까? 그것은 정말로, 정말로 지루해 보인다.

CakePHP와 같은 프레임 워크에서는 'AppController'를 사용하여 전역 적으로 이와 같은 작업을 수행 할 수 있습니다. 즉, 한 번 정의하고 모든 클래스에서 사용할 수있게 만들 수 있습니다. Slim은이 기능을 제공하지 않습니까? 그렇지 않다면 그것은 심각한 단점이 있습니다. http://slimframework.com/docs/tutorial/first-app.html - - 그들이 당신이 먼저 응용 프로그램 자습서를 보면

: -


편집 내가 더 문제를 시도하고 설명하기 위해 만들어 놓은 의견 중 하나에서이 추가 해요 컨테이너에 PDO 데이터베이스 연결을 추가합니다.

하위 디렉토리에 100 개의 별도 클래스가 있고 (예 : ../classes/ 디렉토리가 있음), spl_autoload_register()을 사용하여 index.php에 자동로드를 가정 해 봅시다. 컨테이너는 해당 클래스에서 사용할 수 없습니다.

내가 100 개의 별도의 시간을 전달해야한다면, 수업을 하나씩 사용할 때마다 PDO 연결을 얻으려고하면 그 코드가 매우 반복적입니다. 즉 DRY가 아닙니다.

+0

슬림은 기본적으로 DIC로 여드름을 사용하고 있으므로 어쩌면 그 부분을 살펴 봐야할까요? http://pimple.sensiolabs.org/ –

+0

AFAIK, 여드름에는 생성자 의존성을 자동으로 해결할 방법이 없습니다. 따라서 모든 클래스를 컨테이너에 등록해야합니다. 그러나 이것이 DRY에 반대하는 이유는 모르겠다. 컨테이너에 클래스를 등록 할 때 컨테이너의 종속성을 계속 주입하므로 모든 클래스는 한 번만 등록되고 해결됩니다 ... 여드름 사이트의 예를 확인하십시오. –

+0

@MagnusEriksson이 예제를 제공합니다 - 첫 번째 애플리케이션 자습서 (http://www.slimframework.com/docs/tutorial/first-app.html)를 보면 컨테이너에 PDO 데이터베이스 연결이 추가됩니다. 이제 .. 하위 디렉토리에 100 개의 별도 클래스가 있다고 가정 해 봅시다. (예를 들어 ../classes/ 디렉토리가 있습니다) spl_autoload_register()를 사용하여 index.php에 자동로드합니다. 컨테이너는 해당 클래스에서 사용할 수 없습니다. 본질적으로 동일한 코드를 100 번 반복하기 때문에 각 클래스에서 PDO 연결을 얻으려면 100 번이나 쓰는 것이 좋습니다. DRY가 아닙니다. – Andy

답변

7

슬림은 기본적으로 Pimple과 함께 제공됩니다. 일부 개발자는 Pimple이 의존성 주입 컨테이너가 아니라 서비스 검색기가 자체 의존성을 해결하지 않기 때문에 등록해야한다고 주장합니다 (그들과 동의하는 경향이 있음).

슬림 3은 PHP-DI가 수행하는 Container interop interface을 구현하는 종속성 관리자와 함께 작동합니다.

this package으로 이동하십시오. 이것은 내가 프로젝트에 사용하고있는 것이며, 단지 autowiring 때문에 놀랍습니다. 이를 간단히 말하면, PHP-DI는 클래스의 생성자를 읽어 들여서 주입해야 할 것을 이해합니다. 여드름으로 종속성을 등록 할 필요가 없습니다.

가끔 나는 더 단순하기 때문에 PHP-DI가 Pimple을 Slim의 기본 DI 컨테이너로 대체 할 것이라고 생각합니다.

<?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 번 전달해야합니까? 그것은 정말로, 정말로 지루한 것처럼 보인다. 당신이 PHP-DI와 함께 번들로 슬림를 사용하는 경우

, 문제는 인 타이틀에서 autowiring과을 를 해결된다. :)

+0

솔루션에 대한 의견이 있으십니까? (사용자 'Audrey Roberts')? 귀하의 답변을 수락했지만 다른 솔루션은 기본 Slim 설치와 함께 제공되지 않는 것을 사용하는 것에 의존하지 않으며 더 단순 해 보입니다. – Andy

+3

Audrey의 솔루션은 완전히 수용 가능합니다. 그것은 Slim의 튜토리얼에서 제공됩니다. 그러나 생성자 인자로서 컨테이너를 전달하는 것은 의존성 삽입의 목적을 정말로 무효화하고 테스트 가능성의 합병증을 추가합니다. 더 간단 해 보입니다. –

+1

Slim에 대한 문서는 Dependency Injection과 관련하여 상당히 유용합니다. (다소 성가신 일입니다.) 실제로 제대로 사용하지는 않습니다. 이것은 실제로 제가 올바르게 인식하고 DI와 Slim을 읽고 오랜 시간을 보냈지만 제대로 사용하지 않는다는 것을 알게되었습니다. 매우 실망 스럽습니다. autowiring과 Slim Bridge를 좀 더 자세하게 살펴 보도록하겠습니다. 제안 해 주셔서 감사합니다. – Andy

2

이 작업을 수행하는 가장 간단한 방법은 지금과 같다 :

index.php를

$app->get('/mytest', '\TestController:mytest'); 

TestController.php

class TestController { 

    protected $ci; 

    public function __construct(Slim\Container $ci) { 
     //var_dump($ci); 
     $this->ci = $ci; 
    } 

    public function mytest() { 
     $sql = ''; // e.g. SQL query 
     $stmt = $this->ci->db->prepare($sql); 
    } 
} 

내가 잘 모르겠어요 이것은 "올바른"방법입니다. 그러나 어떤 일이 발생하는지는 TestController의 생성자가 tainer를 첫 번째 인수로 사용합니다. 이것은 자신의 문서에서 언급 한 : 당신이 TestController::mytest() 같은 기능을 사용할 때 http://www.slimframework.com/docs/objects/router.html#container-resolution

따라서는 자신의 첫 번째 응용 프로그램을 다음과 같은 경우 (의 index.php에서 설정 한 PDO 데이터베이스 인스턴스로, 컨테이너에서 아무것도에 액세스 할 수 있습니다 예제 튜토리얼).

제가 말했듯이 그것이 "올바른"방법 일지는 확실하지 않지만 작동합니다.

var_dump($ci) 줄의 주석 처리를 제거하면 슬림 컨테이너 객체가 표시됩니다.

누구든지이 점에 대한 의견이 있으시면 알려 주시기 바랍니다.

관련 문제