आपके पास एक अच्छा सवाल है। आपके समाधान के साथ शायद कुछ ट्रेड-ऑफ हैं। अंतिम उत्तर वास्तव में इस बात पर निर्भर करता है कि आपके द्वारा प्लेटफ़ॉर्म आश्रित का क्या अर्थ है। उदाहरण के लिए, यदि आप बाहरी अनुप्रयोगों को शुरू करने के लिए एक प्रक्रिया शुरू कर रहे हैं और आप बस एक आवेदन और दूसरे के बीच स्विच कर रहे हैं, तो आप संभवतः इसे बहुत अधिक जटिलता के बिना संभाल सकते हैं। यदि आप देशी पुस्तकालयों के साथ पी / इनवोक की बात कर रहे हैं, तो थोड़ा और करना होगा। हालाँकि यदि आप उन पुस्तकालयों के साथ जुड़ रहे हैं जो केवल एक मंच पर मौजूद हैं, तो आपको संभवतः कई विधानसभाओं का उपयोग करने की आवश्यकता होगी।
बाहरी ऐप्स
आपको शायद #if
इस स्थिति में कथन का उपयोग करने की आवश्यकता नहीं होगी । बस कुछ इंटरफेस सेट करें, और प्रति प्लेटफॉर्म एक कार्यान्वयन हो। प्लेटफॉर्म का पता लगाने और सही उदाहरण प्रदान करने के लिए एक कारखाने का उपयोग करें।
कुछ मामलों में यह एक विशिष्ट प्लेटफॉर्म के लिए संकलित बाइनरी है, लेकिन निष्पादन योग्य और सभी मापदंडों के नाम समान हैं। उस मामले में यह सही निष्पादन योग्य हल करने की बात है। बल्क ऑडियो कन्वर्टर ऐप के लिए, जो विंडोज और लिनक्स पर चल सकता है, मेरे पास एक बाइनरी नाम का एक स्थिर इनिशियलाइज़र था।
public class AudioProcessor
{
private static readonly string AppName = "lame";
private static readonly string FullAppPath;
static AudioProcessor()
{
var platform = DetectPlatform();
var architecture = Detect64or32Bits();
FullAppPath = Path.combine(platform, architecture, AppName);
}
}
यहां कुछ भी नहीं फैंसी। बस अच्छे राजभाषा 'फैशन वर्ग।
पी / आह्वान
P / Invoke थोड़ा पेचीदा है। लब्बोलुआब यह है कि आपको यह सुनिश्चित करने की आवश्यकता है कि देशी पुस्तकालय का सही संस्करण लोड किया गया है। खिड़कियों पर आप P / Invoke करेंगे SetDllDirectory()
। विभिन्न प्लेटफार्मों को उस कदम की आवश्यकता नहीं हो सकती है। तो यह वह जगह है जहाँ चीजें गड़बड़ हो सकती हैं। आपको #if
अपने पुस्तकालय पथ को हल करने के लिए किस कॉल का उपयोग किया जाता है, इसे नियंत्रित करने के लिए आपको बयानों का उपयोग करने की आवश्यकता हो सकती है - खासकर यदि आप इसे अपने वितरण पैकेज में शामिल कर रहे हैं।
पूरी तरह से अलग प्लेटफॉर्म आश्रित पुस्तकालयों से जोड़ना
पुराने स्कूल बहु-लक्ष्यीकरण दृष्टिकोण यहाँ उपयोगी हो सकता है। हालाँकि यह बहुत कुरूपता के साथ आता है। उन दिनों में जहां कुछ परियोजनाओं ने एक ही DLL लक्ष्य सिल्वरलाइट, WPF और संभावित UAP के लिए प्रयास किया था, आपको कई बार विभिन्न संकलन टैग के साथ आवेदन को संकलित करना होगा। उपरोक्त प्रत्येक प्लेटफ़ॉर्म के साथ चुनौती यह है कि जब वे समान अवधारणाओं को साझा करते हैं, तो प्लेटफ़ॉर्म पर्याप्त रूप से भिन्न होते हैं कि आपको उन अंतरों के आसपास काम करना होगा। यह वह जगह है जहाँ हम नरक में जाते हैं #if
।
इस दृष्टिकोण को .csproj
प्लेटफ़ॉर्म आश्रित संदर्भों को संभालने के लिए फ़ाइल को हाथ से संपादित करने की भी आवश्यकता होती है । चूँकि आपकी .csproj
फ़ाइल एक MSBuild फ़ाइल है, यह पूरी तरह से एक ज्ञात और पूर्वानुमेय तरीके से करना संभव है।
# नरक
आप #if
बयानों का उपयोग करके कोड के अनुभागों को चालू और बंद कर सकते हैं ताकि अनुप्रयोगों के बीच मामूली अंतर को संभालने में प्रभावी हो। सतह पर यह एक अच्छे विचार की तरह लगता है। मैंने इसे ड्रॉइंग कोड को डिबग करने के लिए बॉक्स विज़ुअलाइज़ेशन को चालू और बंद करने के साधन के रूप में भी इस्तेमाल किया।
नंबर 1 समस्या #if
यह है कि जो कोड बंद किया गया है उसका कोई भी मूल्यांकन पार्सर द्वारा नहीं किया जाता है। लायब्रेरी को पुन: व्यवस्थित करने के लिए आपके पास अव्यक्त सिंटैक्स त्रुटियां, या इससे भी बदतर, तर्क त्रुटियां हो सकती हैं। यह रिफैक्टिंग कोड के साथ और भी अधिक समस्याग्रस्त हो जाता है। एक विधि का नाम बदलने या मापदंडों के क्रम को बदलने के रूप में सरल रूप से कुछ सामान्य रूप से ठीक हो जाएगा, लेकिन क्योंकि पार्सर ने कभी भी #if
आपके द्वारा खंडित किए गए कोड को तोड़ दिए गए बयान से आपके द्वारा बताए गए किसी भी चीज का मूल्यांकन नहीं किया है ।
मेरे सभी डिबग कोड जो उस तरीके से लिखे गए थे, रिफ्लेक्टरिंग की एक श्रृंखला के बाद इसे फिर से लिखना पड़ा। फिर से लिखने के दौरान, मैंने उन विशेषताओं को चालू करने और बंद करने के लिए एक वैश्विक कॉन्फ़िगरेशन क्लास का उपयोग किया। इसने इसे रिफ्लेक्टर टूल प्रूफ बनाया, लेकिन एपीआई के पूरी तरह से अलग होने पर ऐसा कोई समाधान नहीं होता है।
मेरा पसंदीदा तरीका
सीखी गई कई दर्दनाक सीखों के आधार पर, और यहां तक कि माइक्रोसॉफ्ट के अपने उदाहरण के आधार पर, मेरी पसंदीदा पद्धति, कई विधानसभाओं का उपयोग करना है।
एक कोर NetStandard विधानसभा सभी इंटरफेस को परिभाषित करने और सभी आम कोड शामिल होंगे। प्लेटफ़ॉर्म आश्रित कार्यान्वयन एक अलग असेंबली में होगा जो शामिल होने पर सुविधाओं को जोड़ देगा।
यह दृष्टिकोण नए कॉन्फ़िगरेशन API और वर्तमान पहचान आर्किटेक्चर द्वारा अनुकरणीय है। जैसा कि आपको अधिक विशिष्ट एकीकरण की आवश्यकता है, आप बस उन नई विधानसभाओं को जोड़ते हैं। वे असेंबली अपने सेट अप में खुद को शामिल करने के लिए एक्सटेंशन फ़ंक्शन भी प्रदान करती हैं। यदि आप एक निर्भरता इंजेक्शन दृष्टिकोण का उपयोग कर रहे हैं, तो वे विस्तार विधियां लाइब्रेरी को सेवाओं को पंजीकृत करने की अनुमति देती हैं।
यह एकमात्र तरीका है जिसके बारे में मुझे पता है कि #if
नरक से बचना है, और एक अलग वातावरण को संतुष्ट करना है।