2016-04-25 12 views
5

मैं एपीआई बनाने के लिए स्लिम फ्रेमवर्क 3 का उपयोग कर रहा हूं। ऐप संरचना है: एमवीसीपी (मॉडल, व्यू, कंट्रोलर, प्रदाता)।निर्भरता इंजेक्शन स्लिम फ्रेमवर्क 3

क्या स्लिम निर्भरता मेरे सभी वर्गों को इंजेक्ट करना संभव है?

मैं अपनी सभी निर्भरताओं को स्वत: लोड करने के लिए संगीतकार का उपयोग कर रहा हूं।

मेरे निर्देशिका संरचना इस तरह दिखता है:

/app 
    - controllers/ 
    - Models/ 
    - services/ 
    index.php 
/vendor 
composer.json 

यहाँ मेरी composer.json फ़ाइल है।

{ 
    "require": { 
    "slim/slim": "^3.3", 
    "monolog/monolog": "^1.19" 
    }, 
    "autoload" : { 
    "psr-4" : { 
     "Controllers\\" : "app/controllers/", 
     "Services\\" : "app/services/", 
     "Models\\" : "app/models/" 
    } 
    } 
} 

यहां मेरी index.php फ़ाइल है। फिर, निर्भरता की जा रही संगीतकार द्वारा इंजेक्शन ऑटो रहे

<?php 
use \Psr\Http\Message\ServerRequestInterface as Request; 
use \Psr\Http\Message\ResponseInterface as Response; 

require '../vendor/autoload.php'; 

$container = new \Slim\Container; 
$app = new \Slim\App($container); 

$app->get('/test/{name}', '\Controllers\PeopleController:getEveryone'); 

$app->run(); 

मेरे नियंत्रक इस

<?php #controllers/PeopleController.php 

namespace Controllers; 

use \Psr\Http\Message\ServerRequestInterface as Request; 
use \Psr\Http\Message\ResponseInterface as Response; 


class PeopleController 
{ 
    protected $peopleService; 

    protected $ci; 
    protected $request; 
    protected $response; 

    public function __construct(Container $ci, PeopleService $peopleService) 
    { 
     $this->peopleService = $peopleService; 
     $this->ci = $ci; 
    } 

    public function getEveryone($request, $response) 
    { 
     die($request->getAttribute('name')); 

     return $this->peopleService->getAllPeoples(); 
    } 
} 

मेरे PeopleService फ़ाइल की तरह दिखता है इस तरह दिखता है:

<?php 

namespace Services; 

use Model\PeopleModel; 
use Model\AddressModel; 
use Model\AutoModel; 


class PeopleService 
{ 
    protected $peopleModel; 
    protected $autoModel; 
    protected $addressModel; 

    public function __construct(PeopleModel $peopleModel, AddressModel $addressModel, AutoModel $autoModel) 
    { 
     $this->addressModel = $addressModel; 
     $this->autoModel = $autoModel; 
     $this->peopleModel = $peopleModel; 
    } 

    public function getAllPeopleInfo() 
    { 
     $address = $this->addressModel->getAddress(); 
     $auto = $this->autoModel->getAutoMake(); 
     $person = $this->peopleModel->getPeople(); 

     return [ 
      $person[1], $address[1], $auto[1] 
     ]; 
    } 
} 

Models/AddressModels.php

<?php 

namespace Model; 

class AddressModel 
{ 

    public function __construct() 
    { 
     // do stuff 
    } 

    public function getAddress() 
    { 
     return [ 
      1 => '123 Maple Street', 
     ]; 
    } 
} 

Models/AutoModel.php

namespace Model; 

class AutoModel 
{ 

    public function __construct() 
    { 
     // do stuff 
    } 

    public function getAutoMake() 
    { 
     return [ 
      1 => 'Honda' 
     ]; 
    } 
} 

Models/PeopleModel.php

<?php 
namespace Model; 

class PeopleModel 
{ 

    public function __construct() 
    { 
     // do stuff 
    } 

    public function getPeople() 
    { 
     return [ 
      1 => 'Bob' 
     ]; 
    } 

} 

त्रुटि मैं अब निम्न त्रुटि हो रही है:

PHP Catchable fatal error: Argument 2 passed to Controllers\PeopleController::__construct() must be an instance of Services\PeopleService, none given, called in /var/www/vendor/slim/slim/Slim/CallableResolver.php on line 64 and defined in /var/www/app/controllers/PeopleController.php on line 21 

प्रश्न मैं अपने सभी सीएल इंजेक्षन कैसे निर्भरता है गधे? स्लिम के डी कंटेनर को स्वचालित रूप से ऐसा करने का कोई तरीका है?

+2

तो आप उन्हें इंजेक्ट करना या ऑटोलोड करना चाहते हैं? यदि आपका ऑटोलोडिंग का मतलब है, तो आप शायद 'index.php' की शुरुआत में' विक्रेता/autoload.php' फ़ाइल को शामिल करना भूल गए हैं। इसमें जेनरेट किए गए ऑटोलोडर हैं। –

+0

ठीक है, यह मेरे मुद्दों में से एक था। धन्यवाद! मैंने इंडेक्स को अपडेट किया है।विक्रेता को स्वत: लोड PHP फ़ाइल शामिल करने के लिए php। मैंने अब जिस त्रुटि को प्राप्त कर रहा हूं उसे शामिल करने के लिए प्रश्न को अद्यतन किया है। फिर, मुद्दा यह है कि निर्भरता कैसे मेरी कक्षाओं को इंजेक्ट करें। –

+0

ठीक है, त्रुटि आत्म-व्याख्या है। यहाँ क्या स्पष्ट नहीं है? –

उत्तर

4

जब आप मार्ग कॉल करने योग्य स्लिम में कक्षा का संदर्भ देते हैं तो इसके लिए डीआईसी से पूछेगा। यदि डीआईसी के पास उस वर्ग के नाम के लिए पंजीकरण नहीं है, तो यह कक्षा के लिए एकमात्र तर्क के रूप में कंटेनर को गुजरने, कक्षा को तुरंत चालू कर देगा।

$container['\Services\PeopleService'] = function ($c) { 
    $peopleModel = new Models\PeopleModel; 
    $addressModel = new Models\AddressModel; 
    $autoModel = new Models\AutoModel; 
    return new Services\PeopleService($peopleModel, $addressModel, $autoModel); 
}; 
:

$container = $app->getContainer(); 
$container['\Controllers\PeopleController'] = function ($c) { 
    $peopleService = $c->get('\Services\PeopleService'); 
    return new Controllers\PeopleController($c, $peopleService); 
}; 

बेशक, आप अब PeopleService के लिए एक डीआईसी कारखाने की जरूरत है:

इसलिए, अपने नियंत्रक के लिए सही निर्भरता सुई, तो आप सिर्फ अपने खुद के डीआईसी कारखाना बनाने के लिए

(यदि पीपलमोडेल, एड्रेसमोडेल, या ऑटोमोडेल पर निर्भरताएं थीं, तो आप उन लोगों के लिए डीआईसी कारखानों का निर्माण भी करेंगे।)

+0

क्या स्लिम आपको कंटेनर को * हर * कक्षा में पास करने की आवश्यकता है जिसकी आवश्यकता है? यह एक बहुत ही शुष्क दृष्टिकोण की तरह प्रतीत नहीं होता है। मुझे केकपीएचपी के साथ काम करने के लिए उपयोग किया जाता है और ऐसा लगता है कि इसका उपयोग करते समय चीजें "वैश्विक रूप से" उपलब्ध होती हैं (संभवतः ऐपमोडेल और ऐप कंट्रोलर के कारण)। यह स्लिम में लगता है कि आपको हर बार कंटेनर जैसी चीज़ों को पारित करने की आवश्यकता होती है? तो अगर मेरे पास 100 कक्षाएं हैं, तो मुझे 100 गुना से ऊपर के कोड के बराबर कोड का उपयोग करना होगा? – Andy

+0

यह आप पर निर्भर है। वैश्विक स्थैतिक फ़ंक्शन बनाने से रोकने के लिए कुछ भी नहीं है जो आपको कंटेनर को पकड़ने की अनुमति देता है। व्यक्तिगत रूप से, मैं युग्मन के उस स्तर को नापसंद करता हूं, इसलिए इसे इस तरह से न करें। –

संबंधित मुद्दे