पहचान
एमवीवीएम में सामान्य अभ्यास यह है कि उनके दृश्यमॉडल को एक निर्भरता इंजेक्शन (डीआई) कंटेनर से हल करके नजारे खोजे जाएं । यह स्वचालित रूप से होता है जब कंटेनर को व्यू क्लास का एक उदाहरण प्रदान करने (समाधान) के लिए कहा जाता है। कंटेनर ViewModel को दृश्य के एक निर्माता को कॉल करके View में इंजेक्ट करता है जो एक ViewModel पैरामीटर को स्वीकार करता है; इस योजना को नियंत्रण का उलटा (IoC) कहा जाता है ।
DI के लाभ
यहां मुख्य लाभ यह है कि कंटेनर को उस समय के निर्देशों के साथ रन टाइम पर कॉन्फ़िगर किया जा सकता है , जिस प्रकार से हम उससे अनुरोध करते हैं। यह हमारे द्वारा वास्तव में उपयोग किए जाने वाले प्रकारों (दृश्य और दृश्यमॉडल) को हल करने के लिए निर्देश देकर अधिक से अधिक परीक्षण करने की अनुमति देता है, लेकिन एप्लिकेशन के लिए यूनिट परीक्षण चलाते समय इसे अलग तरह से निर्देश देता है। बाद के मामले में आवेदन में एक यूआई भी नहीं होगा (यह नहीं चल रहा है; बस परीक्षण हैं) इसलिए कंटेनर "सामान्य" प्रकारों के स्थान पर नकली को हल करेगा जब आवेदन चलता है।
DI से उपजी समस्याएं
अब तक हमने देखा है कि डीआई दृष्टिकोण आवेदन घटकों के निर्माण पर एक अमूर्त परत जोड़कर आवेदन के लिए आसान परीक्षण क्षमता की अनुमति देता है। इस दृष्टिकोण के साथ एक समस्या है: यह Microsoft अभिव्यक्ति ब्लेंड जैसे दृश्य डिजाइनरों के साथ अच्छा नहीं खेलता है ।
समस्या यह है कि सामान्य अनुप्रयोग रन और यूनिट टेस्ट रन दोनों में, किसी को कंटेनर को निर्देश के साथ सेट करना होगा कि किस प्रकार को हल करना है; इसके अलावा, किसी को कंटेनर को व्यूज़ को हल करने के लिए कहना होगा ताकि व्यूमॉडल को उसमें इंजेक्ट किया जा सके।
हालाँकि, डिज़ाइन समय में हमारा कोई कोड नहीं चल रहा है । डिजाइनर हमारे दृश्यों के उदाहरण बनाने के लिए प्रतिबिंब का उपयोग करने का प्रयास करता है, जिसका अर्थ है कि:
- यदि व्यू कंस्ट्रक्टर को ViewModel उदाहरण की आवश्यकता होती है, तो डिज़ाइनर व्यू को तुरंत देख नहीं पाएगा - यह किसी न किसी तरीके से त्रुटि करेगा
- यदि व्यू में एक पैरामीटर रहित कंस्ट्रक्टर है, तो व्यू को त्वरित रूप से बदल दिया
DataContext
जाएगा , लेकिन इसका परिणाम यह होगा null
कि हमें डिजाइनर में "खाली" दृश्य मिलेगा - जो बहुत उपयोगी नहीं है
ViewModelLocator दर्ज करें
ViewModelLocator इस तरह उपयोग किया जाने वाला एक अतिरिक्त अमूर्त है:
- व्यू अपने आप को अपने संसाधनों के एक हिस्से के रूप में एक ViewModelLocator झटपट करता है और लोकेटर के ViewModel संपत्ति के लिए अपने DataContext को डेटाबाइंड करता है।
- लोकेटर किसी तरह पता लगाता है कि क्या हम डिजाइन मोड में हैं
- यदि डिज़ाइन मोड में नहीं है, तो लोकेटर एक ViewModel देता है जिसे वह DI कंटेनर से हल करता है, जैसा कि ऊपर बताया गया है
- यदि डिजाइन मोड में, लोकेटर एक निश्चित "डमी" ViewModel को अपने तर्क का उपयोग करके लौटाता है (याद रखें: डिजाइन समय में कोई कंटेनर नहीं है!)। यह ViewModel आमतौर पर डमी डेटा के साथ आता है
बेशक इसका मतलब यह है कि व्यू के पास एक पैरामीटर रहित कंस्ट्रक्टर होना चाहिए, जिसके साथ शुरुआत होगी (अन्यथा डिजाइनर इसे तुरंत इंस्टाल नहीं कर पाएगा)।
सारांश
ViewModelLocator एक मुहावरा है जो आपको अपने MVVM एप्लिकेशन में DI के लाभों को रखने की अनुमति देता है जबकि आपके कोड को दृश्य डिजाइनरों के साथ अच्छा खेलने की अनुमति देता है। इसे कभी-कभी आपके आवेदन की "मिश्रणशीलता" कहा जाता है (अभिव्यक्ति मिश्रण की चर्चा करते हुए)।
ऊपर पचाने के बाद, एक व्यावहारिक उदाहरण देखने के लिए यहाँ ।
अंत में, डेटा टेम्प्लेट का उपयोग करना ViewModelLocator का उपयोग करने का विकल्प नहीं है, लेकिन आपके UI के कुछ हिस्सों के लिए स्पष्ट दृश्य / ViewModel जोड़े का उपयोग करने का विकल्प है। अक्सर आप पा सकते हैं कि एक ViewModel के लिए एक दृश्य को परिभाषित करने की कोई आवश्यकता नहीं है क्योंकि आप इसके बजाय डेटा टेम्पलेट का उपयोग कर सकते हैं।