2014-09-11 7 views
9

मैं यह पता लगाने की कोशिश कर रहा हूं कि app->bind और app->singleton के बीच का अंतर क्या है जब लैरावेल में सेवा प्रदाता की स्थापना की जाती है। मैं इस धारणा के तहत था कि अगर मैं singleton पंजीकृत करता हूं तो यह ऑब्जेक्ट का एक ही उदाहरण वापस लौटाएगा जब इसे बनाम bind कहा जाता है जो एक नया उदाहरण होगा।लारवेल अंतर 'ऐप-> बाइंड' और 'ऐप-> सिंगलटन' के बीच?

यहाँ सरल उदाहरण है:

फसाड:

use Illuminate\Support\Facades\Facade; 

class DataFacade extends Facade 
{ 
    protected static function getFacadeAccessor() { 
     return 'Data'; 
    } 
} 

ServiceProvider:

use Illuminate\Support\ServiceProvider; 

class DataServiceProvider extends ServiceProvider 
{ 
    public function register() { 
     $this->app->singleton('Data', function() { 
      return new Data; 
     }); 
    } 
} 

कक्षा:

class Data 
{ 
    public $data = []; 

    public function get($key) 
    { 
     return isset($this->data[$key]) ? $this->data[$key] : null; 
    } 

    public function set($key, $val) 
    { 
     $this->data[$key] = $val; 
    } 
} 

हम की तरह कुछ करते हैं:

$instance = App::make('Data'); 
$instance->set('foo', 'foo'); 

$instance2 = App::make('Data'); 

echo $instance->get('foo'); 
echo $instance2->get('foo'); 

और रन है कि हम foo साथ bind और singleton के बीच उचित व्यवहार देखेंगे एक बार क्रमश: दो बार बाहर मुद्रित किया जा रहा है और फिर। लेकिन अगर हम ऐसा तरह मुखौटा के माध्यम से चलाने:

Data::set('test', 'test'); 
Data::set('cheese', 'cheese'); 

मैं दोनों test और cheese उपलब्ध होने की उम्मीद होती है और जब यह एक bind है मुझे यकीन है कि मैं क्या माध्यम से उपलब्ध होने की अपेक्षा करेंगे नहीं कर रहा हूँ यह एक सिंगलटन है जब मुखौटा, लेकिन ऐसा लगता है कि कोई फर्क नहीं पड़ता है।

यह सब कुछ singleton के रूप में व्यवहार करने का मुखौटा है?

+0

आप पहले से ही अंतर जानते हैं! –

+0

आपने 'बाइंड 'का उल्लेख किया है - लेकिन आपका प्रश्न कभी भी बाध्य नहीं करता है। –

+0

लेकिन क्या मुखौटा सेवा प्रदाता को कॉल नहीं करता है जो बांधता है? – Rob

उत्तर

21

आपका प्रश्न थोड़ा उलझन में है और किसी के पास जवाब देने के लिए सभी जानकारी नहीं है, लेकिन यह एक भ्रमित विषय है, इसलिए बुरा मत मानो। यहाँ एक ठहरनेवाला में मदद मिल सकती है कि आप बेहतर समझते हैं, और सवाल आप से पूछना चाहता था पूछना है (यह भी, मैं Laravel के लिए काफ़ी नया हूँ, इसलिए मैं इन के साथ बंद आधार हो सकता है)

  1. make विधि करने के लिए प्रयोग किया जाता है वस्तुओं को तत्काल करें। जब आप App::make('Data') कहते हैं तो आप कक्षा Data से ऑब्जेक्ट को तत्काल करने के लिए लार्वेल को बता रहे हैं।

  2. 1. नंबर पर आप makeफोन और पहले से ही सेवा कंटेनर में कुछ करने के लिए स्ट्रिंग Data बाध्य है एक चेतावनी है, Laravel सेवा के बजाय वापस आ जाएगी।इसका मतलब यह हो सकता है Laravel एक नई सेवा वस्तु को दर्शाता है, या यह Laravel एक सेवा सिंगलटन

  3. या नहीं, Laravel एक सेवा के लिए एक सिंगलटन या एक उदाहरण देता पर निर्भर करता है सेवा ही था रिटर्न मतलब हो सकता है

  4. make विधि कुछ भी बाध्य नहीं है

  5. आप आवेदन वस्तु की bind विधि, निम्न विधि प्रोटोटाइप public function bind($abstract, $concrete = null, $shared = false)

  6. 01 के साथ कंटेनर वर्ग पर परिभाषित के साथ सेवाओं के लिए बाध्य
  7. उस तीसरे $shared पैरामीटर देखें? यदि यह सच है तो आपकी सेवा एक सिंगलटन लौटाएगी। यदि यह गलत है तो आपकी सेवा उदाहरण वापस कर देगी। # 7, यहाँ singleton

    #File: vendor/laravel/framework/src/Illuminate/Container/Container.php 
    public function singleton($abstract, $concrete = null) 
    { 
        $this->bind($abstract, $concrete, true); 
    } 
    

    अपने उदाहरणों में की परिभाषा आप बाध्यकारी रहे हैं इसके बाद के संस्करण:

  8. आवेदन वस्तु की singleton विधि बाध्यकारी सेवाओं के लिए एक विधि

पुन है कंटेनर में सेवा Data। एक अग्रणी केस सेवा नाम का उपयोग करने से समस्याएं पैदा हो रही हैं - data बेहतर विकल्प होगा। अपने register विधि किसी कारण से नहीं कहा जाता है, तो make अभी भी अपने वैश्विक वर्ग Data

अपने फसाड के बारे में के साथ एक वस्तु का दृष्टांत होगा - एक फसाड उदाहरण/सिंगलटन सत्ता की अतिरिक्त परत है। यहाँ विधि जहां मुखौटा वर्ग getFacadeAccessor से स्ट्रिंग का उपयोग करता है एक स्थिर कॉल से एक वस्तु वापस जाने के लिए है

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php 
protected static function resolveFacadeInstance($name) 
{ 
    if (is_object($name)) return $name; 

    if (isset(static::$resolvedInstance[$name])) 
    { 
     return static::$resolvedInstance[$name]; 
    } 

    return static::$resolvedInstance[$name] = static::$app[$name]; 
} 

तो, एक मुखौटा $app[$name]; का उपयोग करता है कंटेनर से एक सेवा हड़पने के लिए। यह ArrayAccess है, इसलिए यदि हम offsetGet

public function offsetGet($key) 
{ 
    return $this->make($key); 
} 

की परिभाषा को देखो हम देखते हैं ArrayAccessmake के लिए एक कॉल गिर्द घूमती है। इसका मतलब है कि यदि आपके पास कोई बाध्य सेवा नहीं है, तो मुखौटा पहुंच किसी ऑब्जेक्ट को तुरंत चालू करेगी। यदि आपके पास सिंगलटन/साझा सेवा के रूप में सेवा है, तो मुखौटा पहुंच उस सिंगलटन को वापस कर देगी। यदि आपके पास एक सिंगलटन/साझा सेवा के रूप में सेवा नहीं है, तो मुखौटा पहुंच एक नई वस्तु को तुरंत चालू करेगी।

हाउवर, फेकाडे स्वयं किसी भी ऑब्जेक्ट को स्टोर करेगा जो इसे static::$resolvedInstance के अंदर तुरंत चालू करता है, और भविष्य में कॉल का मुखौटा इसी उदाहरण को वापस कर देगा। इसका मतलब है कि फेकाडे एक्सेस दूसरे सिंगलटन कार्यान्वयन को पेश करता है। एक ऑब्जेक्ट के रूप में बंधे एक सेवा को एप्लिकेशन ऑब्जेक्ट पर संग्रहीत किया जाएगा, एक मुखौटा के माध्यम से उपयोग की जाने वाली सेवा Facade कक्षा पर सिंगलटन के रूप में संग्रहीत की जाएगी।

+1

उस महान स्पष्टीकरण के लिए धन्यवाद, जो चीजों को स्पष्ट करने में मदद करता है। मैं मुखौटा पर सिंगलटन के बारे में टुकड़ा याद कर रहा था। अगर मैं सही ढंग से समझता हूं, तो ऊपर दिए गए मेरे उदाहरण का जिक्र करते हुए, यदि कोई मुखौटा एक नया उदाहरण बनाता है तो यह एक सिंगलटन होगा जो हमेशा '$ instance1'' का संदर्भ देगा जो यह आईओसी/सेवा प्रदाता बाध्यकारी के माध्यम से बनाता है? क्या इसका मतलब यह है कि एक मुखौटा हमेशा एक सिंगलटन के रूप में "कार्य" करेगा चाहे इस बात पर ध्यान दिए बिना कि आपका सेवा प्रदाता एक नया उदाहरण/सिंगलटन के रूप में स्थापित है या नहीं? यदि हां, तो फेकाडे का उपयोग करके इसके चारों ओर एक रास्ता है? मुझे जोड़ना चाहिए, क्या एक परिदृश्य है जहां हम चाहते हैं? – Rob

+1

@Rob - मैं अभी तक एक विशेषज्ञ से बहुत दूर हूं, लेकिन हां, ऐसा लगता है कि एक फेकाडे एक ऑब्जेक्ट को एक बार चालू कर देगा, और तब हमेशा उसी कॉल का उपयोग विधि कॉल के लिए करेगा, ** भले ही कंटेनर बाध्य है । आप इसे एक सेवा विधि के साथ परीक्षण कर सकते हैं जो '$ $ को वापस लौटाता है, विधि को एक मुखौटा के माध्यम से कॉल करता है, और फिर राज्य जांच करता है। मेरा संदेह यह है कि "सेवाओं को डिफ़ॉल्ट रूप से सिंगलटन नहीं हैं" के साथ प्रदर्शन समस्याओं से बचने के लिए एक जानबूझकर निर्णय है। –

+0

मुझे लगता है कि मुखौटे यहां भ्रम पैदा करते हैं, वे हमेशा साझा उदाहरणों के साथ बाध्य होने पर भी कई उदाहरणों के बजाय सिंगलटन को मजबूर करते हैं। – Vedmant

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