Dynamics AX 2012 में किस उपवर्ग को तत्काल बनाना है, यह जानने के लिए SysExtension फ्रेमवर्क का उपयोग करना
प्रकाशित: 16 फ़रवरी 2025 को 12:26:07 am UTC बजे
आखरी अपडेट: 12 जनवरी 2026 को 8:43:24 am UTC बजे
यह आर्टिकल बताता है कि Dynamics AX 2012 और Dynamics 365 for Operations में कम जाने-पहचाने SysExtension फ्रेमवर्क का इस्तेमाल कैसे करें, ताकि एट्रिब्यूट डेकोरेशन के आधार पर सब-क्लास को इंस्टैंशिएट किया जा सके, जिससे प्रोसेसिंग क्लास हायरार्की का आसानी से एक्सटेंसिबल डिज़ाइन बन सके।
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
इस पोस्ट में दी गई जानकारी Dynamics AX 2012 R3 पर आधारित है। यह दूसरे वर्शन के लिए वैलिड हो भी सकती है और नहीं भी। (अपडेट: मैं कन्फर्म कर सकता हूँ कि इस आर्टिकल में दी गई जानकारी Dynamics 365 for Operations के लिए भी वैलिड है)
Dynamics AX में प्रोसेसिंग क्लास को इम्प्लीमेंट करते समय, आपको अक्सर एक क्लास हायरार्की बनानी पड़ती है जिसमें हर सबक्लास एक एनम वैल्यू से मैच करता है या उसमें कोई और डेटा कपलिंग होती है। एक क्लासिक डिज़ाइन यह है कि सुपर क्लास में एक कंस्ट्रक्ट मेथड हो, जिसमें एक स्विच होता है जो यह तय करता है कि इनपुट के आधार पर किस क्लास को इंस्टैंशिएट करना है।
यह प्रिंसिपल तौर पर ठीक काम करता है, लेकिन अगर आपके पास कई अलग-अलग पॉसिबल इनपुट हैं (एक एनम में कई एलिमेंट या शायद इनपुट कई अलग-अलग वैल्यू का कॉम्बिनेशन है), तो इसे मेंटेन करना मुश्किल और एरर-प्रोन हो सकता है और डिज़ाइन में हमेशा यह नुकसान होता है कि अगर आप कभी कोई नया सबक्लास जोड़ते हैं या यह बदलते हैं कि किस इनपुट के आधार पर कौन सा सबक्लास इस्तेमाल किया जाना चाहिए, तो आपको उस कंस्ट्रक्ट मेथड को बदलना होगा।
अच्छी बात ये है कि ऐसा करने का एक बहुत ही अच्छा, लेकिन बदकिस्मती से बहुत कम जाना-माना तरीका है, यानी SysExtension फ्रेमवर्क का इस्तेमाल करना।
यह फ्रेमवर्क उन एट्रिब्यूट्स का फ़ायदा उठाता है जिनका इस्तेमाल आप अपनी सब क्लास को डेकोरेट करने के लिए कर सकते हैं ताकि सिस्टम यह पता लगा सके कि किस सब क्लास का इस्तेमाल क्या हैंडल करने के लिए किया जाना चाहिए। आपको अभी भी एक कंस्ट्रक्ट मेथड की ज़रूरत होगी, लेकिन अगर इसे सही तरीके से किया जाए, तो नई सब क्लास जोड़ते समय आपको इसे कभी भी मॉडिफ़ाई नहीं करना पड़ेगा।
आइए एक इमेजिनरी उदाहरण देखते हैं और मान लेते हैं कि आप एक हायरार्की इम्प्लीमेंट करने जा रहे हैं जो InventTrans टेबल के आधार पर किसी तरह की प्रोसेसिंग करती है। कौन सी प्रोसेसिंग करनी है यह रिकॉर्ड्स के StatusReceipt और StatusIssue पर निर्भर करता है, साथ ही इस बात पर भी कि रिकॉर्ड्स SalesLine, PurchLine से संबंधित हैं या दोनों में से किसी से भी नहीं। अभी से, आप बहुत सारे अलग-अलग कॉम्बिनेशन देख रहे हैं।
तो मान लीजिए कि आप जानते हैं कि अभी आपको बस कुछ ही कॉम्बिनेशन को हैंडल करना है, लेकिन आप यह भी जानते हैं कि समय के साथ आपसे और भी ज़्यादा कॉम्बिनेशन को हैंडल करने के लिए कहा जाएगा।
चलिए इसे काफ़ी आसान रखते हैं और कहते हैं कि अभी के लिए आपको सिर्फ़ ReservPhysical या ReservOrdered के StatusIssue के साथ SalesLine से जुड़े रिकॉर्ड्स को हैंडल करना है, बाकी सभी कॉम्बिनेशन को अभी के लिए इग्नोर किया जा सकता है, लेकिन क्योंकि आप जानते हैं कि आपको उन्हें बाद में हैंडल करना होगा, इसलिए आप अपने कोड को इस तरह से डिज़ाइन करना चाहेंगे कि उसे आसानी से एक्सटेंसिबल बनाया जा सके।
अभी के लिए आपकी हायरार्की कुछ ऐसी दिख सकती है:
- मेराप्रोसेसरमेराप्रोसेसर_बिक्रीमेराप्रोसेसर_बिक्री_आरक्षणऑर्डर कियामेराप्रोसेसर_बिक्री_आरक्षणभौतिक
अब, आप सुपर क्लास में आसानी से एक मेथड इम्प्लीमेंट कर सकते हैं जो ModuleInventPurchSales और StatusIssue एनम के आधार पर एक सबक्लास को इंस्टैंशिएट करता है। लेकिन फिर आपको हर बार सबक्लास जोड़ने पर सुपर क्लास को मॉडिफाई करना होगा, और यह असल में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में इनहेरिटेंस का आइडिया नहीं है। आखिर, आपको हर बार नया बैच जॉब जोड़ने पर RunBaseBatch या SysOperationServiceBase को मॉडिफाई करने की ज़रूरत नहीं है।
इसके बजाय, आप SysExtension फ्रेमवर्क का इस्तेमाल कर सकते हैं। इसके लिए आपको एक और क्लास जोड़नी होगी, जिसे SysAttribute को एक्सटेंड करना होगा। इस क्लास का इस्तेमाल उस एट्रिब्यूट के तौर पर किया जाएगा जिससे आप अपनी प्रोसेसिंग क्लास को डेकोरेट कर सकते हैं।
यह क्लास काफी हद तक वैसा ही है जैसे आप SysOperation इम्प्लीमेंटेशन के लिए डेटा कॉन्ट्रैक्ट क्लास बनाते हैं, इसमें उन वैल्यू को पाने और सेट करने के लिए कुछ डेटा मेंबर और parm मेथड होंगे।
हमारे मामले में, ClassDeclaration कुछ ऐसा दिख सकता है:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
आपको सभी डेटा मेंबर्स को इंस्टेंटिएट करने के लिए एक new() मेथड बनाना होगा। अगर आप चाहें तो उनमें से कुछ या सभी को डिफ़ॉल्ट वैल्यू दे सकते हैं, लेकिन मैंने ऐसा नहीं किया है।
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
और आपको हर डेटा मेंबर के लिए एक parm मेथड भी इम्प्लीमेंट करना चाहिए, लेकिन मैंने उन्हें यहाँ छोड़ दिया है क्योंकि मुझे यकीन है कि आप जानते हैं कि यह कैसे करना है - नहीं तो, इसे एक एक्सरसाइज़ ही मान लेते हैं ;-)
अब आप अपनी हर प्रोसेसिंग क्लास को डेकोरेट करने के लिए अपनी एट्रिब्यूट क्लास का इस्तेमाल कर सकते हैं। उदाहरण के लिए, क्लास डिक्लेरेशन कुछ इस तरह दिख सकते हैं:
StatusIssue::None,
StatusReceipt::None)]
class MyProcessor_Sales extends MyProcessor
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservOrdered,
StatusReceipt::None)]
class MyProcessor_Sales_ReservOrdered extends MyProcessor_Sales
{
}
[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
StatusIssue::ReservPhysical,
StatusReceipt::None)]
class MyProcessor_Sales_ReservPhysical extends MyProcessor_Sales
{
}
आप अपनी क्लास को अपनी मर्ज़ी से कोई भी नाम दे सकते हैं, यहाँ ज़रूरी बात यह है कि आप अपनी क्लास को उन एट्रिब्यूट से सजाएँ जो इस बात से मेल खाते हों कि वे किस तरह की प्रोसेसिंग करते हैं। (लेकिन ध्यान रखें कि Dynamics AX में क्लास हायरार्की के लिए नाम रखने के तरीके हैं और अगर हो सके तो उन्हें फ़ॉलो करना हमेशा अच्छा रहता है)।
अब जब आपने अपनी क्लास को यह पहचानने के लिए सजा दिया है कि उनमें से हर एक किस तरह की प्रोसेसिंग करता है, तो आप ज़रूरत के हिसाब से सब-क्लास के ऑब्जेक्ट्स को इंस्टैंशिएट करने के लिए SysExtension फ्रेमवर्क का फ़ायदा उठा सकते हैं।
अपने सुपर क्लास (MyProcessor) में, आप इस तरह का कंस्ट्रक्ट मेथड जोड़ सकते हैं:
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
MyProcessor ret;
MyProcessorSystemAttribute attribute;
;
attribute = new MyProcessorSystemAttribute( _module,
_statusIssue,
_statusReceipt);
ret = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(MyProcessor), attribute);
if (!ret)
{
// no class found
// here you could throw an error, instantiate a default
// processor instead, or just do nothing, up to you
}
return ret;
}
इस पूरी पोस्ट का सबसे दिलचस्प हिस्सा - और असल में ऑब्जेक्ट (मज़ाक के लिए माफ़ करना) - SysExtensionAppClassFactory क्लास में getClassFromSysAttribute() मेथड है। यह मेथड यह करता है कि यह एक हायरार्की के सुपर क्लास का नाम एक्सेप्ट करता है (और इस सुपर क्लास का हायरार्की में सबसे ऊपर होना ज़रूरी नहीं है; इसका सीधा सा मतलब है कि सिर्फ़ इस क्लास को एक्सटेंड करने वाली क्लास ही एलिजिबल होंगी) और एक एट्रिब्यूट ऑब्जेक्ट।
फिर यह एक क्लास का ऑब्जेक्ट रिटर्न करता है जो बताए गए सुपर क्लास को एक्सटेंड करता है और उससे जुड़े एट्रिब्यूट से डेकोरेट होता है।
ज़ाहिर है, आप कंस्ट्रक्ट मेथड में जितना चाहें उतना वैलिडेशन या लॉजिक जोड़ सकते हैं, लेकिन यहाँ ज़रूरी बात यह है कि एक बार इम्प्लीमेंट होने के बाद, आपको इस मेथड को दोबारा कभी मॉडिफ़ाई नहीं करना पड़ेगा। आप हायरार्की में सब-क्लास जोड़ सकते हैं और जब तक आप उन्हें सही तरीके से डेकोरेट करना पक्का करते हैं, कंस्ट्रक्ट मेथड उन्हें ढूंढ लेगा, भले ही वे लिखे जाने के समय मौजूद न हों।
परफॉर्मेंस का क्या? सच कहूँ तो मैंने इसे बेंचमार्क करने की कोशिश नहीं की है, लेकिन मुझे लगता है कि यह शायद क्लासिक स्विच स्टेटमेंट डिज़ाइन से भी खराब परफॉर्म करता है। हालाँकि, यह देखते हुए कि Dynamics AX में अब तक ज़्यादातर परफॉर्मेंस की दिक्कतें डेटाबेस एक्सेस की वजह से होती हैं, मैं इसके बारे में ज़्यादा चिंता नहीं करूँगा।
बेशक, अगर आप कुछ ऐसा इम्प्लीमेंट कर रहे हैं जिसके लिए हज़ारों ऑब्जेक्ट्स को जल्दी से बनाना होगा, तो आप और जांच करना चाह सकते हैं, लेकिन आम मामलों में जहां आप लंबी प्रोसेसिंग के लिए सिर्फ़ एक ऑब्जेक्ट को इंस्टैंशिएट करते हैं, मुझे शक है कि इससे कोई फ़र्क पड़ेगा। साथ ही, मेरी ट्रबलशूटिंग टिप (अगला पैराग्राफ़) को देखते हुए, ऐसा लगता है कि SysExtension फ्रेमवर्क कैशिंग पर निर्भर करता है, इसलिए एक चालू सिस्टम में मुझे शक है कि इसकी परफ़ॉर्मेंस पर कोई बड़ा असर पड़ेगा।
ट्रबलशूटिंग: अगर कंस्ट्रक्ट मेथड आपकी सब-क्लास को नहीं ढूंढ पाता है, भले ही आपको यकीन हो कि वे सही तरीके से डेकोरेट की गई हैं, तो यह कैशिंग प्रॉब्लम हो सकती है। क्लाइंट और सर्वर दोनों पर कैश क्लियर करने की कोशिश करें। AOS को असल में रीस्टार्ट करने की ज़रूरत नहीं होनी चाहिए, लेकिन यह आखिरी तरीका हो सकता है।
अग्रिम पठन
यदि आपको यह पोस्ट पसंद आई हो, तो आपको ये सुझाव भी पसंद आ सकते हैं:
- Dynamics AX 2012 में कोई वैधानिक निकाय (कंपनी खाते) हटाएँ
- डायनेमिक्स AX 2012 सिस्टमऑपरेशन फ्रेमवर्क त्वरित अवलोकन
- डायनेमिक्स AX 2012 में X++ कोड से Enum के तत्वों पर पुनरावृति कैसे करें
