खोज…


परिचय

डिपेंडेंसी इंजेक्शन (DI) "गुजरती चीजों" के लिए एक फैंसी शब्द है। इसका वास्तव में मतलब यह है कि निर्माणकर्ता के माध्यम से किसी वस्तु की निर्भरता को पार किया जा रहा है और / या वस्तु के अंदर ऑब्जेक्ट निर्माण पर बनाने के बजाय बसता है। निर्भरता इंजेक्शन भी निर्भरता इंजेक्शन कंटेनरों को संदर्भित कर सकता है जो निर्माण और इंजेक्शन को स्वचालित करता है।

कंस्ट्रक्टर इंजेक्शन

वस्तुएँ अक्सर अन्य वस्तुओं पर निर्भर करती हैं। कंस्ट्रक्टर में निर्भरता बनाने के बजाय, पैरामीटर के रूप में निर्भरता को कंस्ट्रक्टर में पारित किया जाना चाहिए। यह सुनिश्चित करता है कि वस्तुओं के बीच तंग युग्मन नहीं है, और वर्ग तात्कालिकता पर निर्भरता को बदलने में सक्षम बनाता है। इसमें कई तरह के फायदे हैं, जिनमें निर्भरता को स्पष्ट करके कोड को पढ़ना आसान बनाने के साथ-साथ परीक्षण को सरल बनाना है क्योंकि निर्भरता को आसानी से बंद किया जा सकता है और अधिक आसानी से नकली किया जा सकता है।

निम्नलिखित उदाहरण में, Component Logger आवृत्ति पर निर्भर करेगा, लेकिन यह एक नहीं बनाता है। इसके बजाय निर्माणकर्ता से तर्क के रूप में पारित किया जाना चाहिए।

interface Logger {
    public function log(string $message);
}

class Component {
    private $logger;

    public function __construct(Logger $logger) {
        $this->logger = $logger;
    }
}

निर्भरता इंजेक्शन के बिना, कोड शायद समान होगा:

class Component {
    private $logger;

    public function __construct() {
        $this->logger = new FooLogger();
    }
}

का उपयोग करते हुए new निर्माता में नई वस्तुओं बनाने के लिए संकेत देता है कि निर्भरता इंजेक्शन का प्रयोग नहीं किया गया था (या अधूरे इस्तेमाल किया गया था), और कोड कसकर युग्मित है कि। यह भी संकेत है कि कोड का अपूर्ण रूप से परीक्षण किया गया है या इसमें भंगुर परीक्षण हो सकते हैं जो प्रोग्राम स्टेट के बारे में गलत धारणा बनाते हैं।

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

सेटर इंजेक्शन

आश्रितों को बसने वालों द्वारा भी इंजेक्शन लगाया जा सकता है।

interface Logger {
    public function log($message);
}

class Component {
    private $logger;
    private $databaseConnection;

    public function __construct(DatabaseConnection $databaseConnection) {
        $this->databaseConnection = $databaseConnection;
    }

    public function setLogger(Logger $logger) {
        $this->logger = $logger;
    }

    public function core() {
        $this->logSave();    
        return $this->databaseConnection->save($this);
    }

    public function logSave() {
         if ($this->logger) {
            $this->logger->log('saving');
        }
    }
}

यह विशेष रूप से दिलचस्प है जब कक्षा की मुख्य कार्यक्षमता काम करने के लिए निर्भरता पर निर्भर नहीं करती है।

यहाँ, केवल आवश्यक निर्भरता DatabaseConnection इसलिए यह कंस्ट्रक्टर में है। Logger निर्भरता वैकल्पिक है और इस तरह निर्माणकर्ता का हिस्सा बनने की आवश्यकता नहीं है, जिससे कक्षा का उपयोग करना आसान हो जाता है।

ध्यान दें कि सेटर इंजेक्शन का उपयोग करते समय, इसे बदलने के बजाय कार्यक्षमता का विस्तार करना बेहतर होता है। एक निर्भरता सेट करते समय, इस बात की पुष्टि नहीं होती है कि निर्भरता कुछ बिंदु पर नहीं बदलेगी, जिससे अप्रत्याशित परिणाम हो सकते हैं। उदाहरण के लिए, एक FileLogger को पहले सेट किया जा सकता था, और फिर एक MailLogger सेट किया जा सकता था। यह इनकैप्सुलेशन को तोड़ता है और लॉग को खोजना मुश्किल बनाता है, क्योंकि हम निर्भरता को बदल रहे हैं।

इसे रोकने के लिए, हमें सेटर इंजेक्शन के साथ एक निर्भरता जोड़ना चाहिए, जैसे:

interface Logger {
    public function log($message);
}

class Component {
    private $loggers = array();
    private $databaseConnection;

    public function __construct(DatabaseConnection $databaseConnection) {
        $this->databaseConnection = $databaseConnection;
    }

    public function addLogger(Logger $logger) {
        $this->loggers[] = $logger;
    }

    public function core() {
        $this->logSave();
        return $this->databaseConnection->save($this);
    }

    public function logSave() {
        foreach ($this->loggers as $logger) {
            $logger->log('saving');
        }
    }
}

इस तरह, जब भी हम कोर कार्यक्षमता का उपयोग करेंगे, यह तब भी नहीं टूटेगा जब कोई लकड़हारा निर्भरता नहीं जोड़ा जाता है, और किसी भी लकड़हारे को जोड़ा जाएगा, भले ही एक और लकड़हारा जोड़ा गया हो। हम इसकी जगह कार्यक्षमता बढ़ा रहे हैं।

कंटेनर इंजेक्शन

डिपेंडेंसी इंजेक्शन कंटेनर (DIC) के संदर्भ में डिपेंडेंसी इंजेक्शन (DI) को कंस्ट्रक्टर इंजेक्शन के सुपरसेट के रूप में देखा जा सकता है। एक DIC आम तौर पर एक क्लास कंस्ट्रक्टर के टाइपिन का विश्लेषण करेगा और अपनी जरूरतों को हल करेगा, उदाहरण के निष्पादन के लिए आवश्यक निर्भरता को प्रभावी ढंग से इंजेक्ट करता है।

सटीक कार्यान्वयन इस दस्तावेज़ के दायरे से परे है, लेकिन इसके दिल में, एक डीआईसी एक वर्ग के हस्ताक्षर का उपयोग करने पर निर्भर करता है ...

namespace Documentation;

class Example
{
    private $meaning;

    public function __construct(Meaning $meaning)
    {
        $this->meaning = $meaning;
    }
}

... स्वचालित रूप से इसे तुरंत करने के लिए, एक ऑटोलरेडिंग सिस्टम पर अधिकांश समय भरोसा करना।

// older PHP versions
$container->make('Documentation\Example');

// since PHP 5.5
$container->make(\Documentation\Example::class);

यदि आप कम से कम 5.5 संस्करण में PHP का उपयोग कर रहे हैं और एक वर्ग का नाम प्राप्त करना चाहते हैं जिस तरह से ऊपर दिखाया जा रहा है, तो सही तरीका दूसरा तरीका है। इस तरह से आप आधुनिक आईडीई का उपयोग करके कक्षा के उपयोग को जल्दी से पा सकते हैं, जो आपको संभावित रिफैक्टिंग में मदद करेगा। आप नियमित स्ट्रिंग्स पर भरोसा नहीं करना चाहते हैं।

इस स्थिति में, Documentation\Example जानता है कि उसे एक Meaning आवश्यकता है, और एक DIC बदले में एक प्रकार का Meaning निकालता है। ठोस कार्यान्वयन की आवश्यकता उपभोग की आवृत्ति पर निर्भर नहीं करती है।

इसके बजाय, हम कंटेनर में नियम बनाते हैं, ऑब्जेक्ट निर्माण से पहले, यह निर्देश देता है कि यदि आवश्यक हो तो विशिष्ट प्रकार को तत्काल कैसे किया जाना चाहिए।

यह एक डीआईसी के रूप में कई फायदे हैं

  • साझा उदाहरण
  • एक प्रकार के हस्ताक्षर को हल करने के लिए एक कारखाना प्रदान करें
  • एक इंटरफ़ेस हस्ताक्षर को हल करें

यदि हम नियमों को परिभाषित करते हैं कि किस प्रकार के विशिष्ट प्रकारों को प्रबंधित करने की आवश्यकता है, तो हम ठीक नियंत्रण प्राप्त कर सकते हैं कि किस प्रकार के साझा किए जाते हैं, तत्काल, या कारखाने से बनाए जाते हैं।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow