Օգտվելով SysExtension Framework-ի միջոցով պարզել, թե որ ենթադասի միջոցով է միանգամից դինամիկայում AX 2012
Հրապարակվել է՝ 16 փետրվարի, 2025 թ., 00:28:15 UTC
Այս հոդվածը նկարագրում է, թե ինչպես օգտագործել քիչ հայտնի SysExtension framework in Dynamics AX 2012 եւ Dynamics 365 օպերացիաների համար միանգամից ենթադասերը հիմնված հատկանիշների դեկորացիաների վրա, ինչը թույլ է տալիս մշակել դասի հիերարխիայի հեշտությամբ էքստենսիվ դիզայն:
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Այս պոստում տեղադրված տեղեկատվությունը հիմնված է Dynamics AX 2012 R3-ի վրա: Այն կարող է կամ չի կարող վավերական լինել այլ տարբերակների համար։ (Թարմացում. կարող եմ հաստատել, որ սույն հոդվածում նշված տեղեկատվությունը նույնպես ուժի մեջ է «Դինամիկա 365» օպերացիայի համար)
Dynamics AX-ում մշակման դասերը իրականացնելիս դուք հաճախ բախվում եք դասի հիերարխիայի ստեղծմանը, որի յուրաքանչյուր ենթաբաժին համապատասխանում է էումի արժույթին կամ ունի որոշ այլ տվյալների միաձուլում: Դասական դիզայնն այն է, որ այդ ժամանակ սուպեր դասի մեջ ունենա կառուցման մեթոդ, որն ունի մի switch, որը որոշում է, թե որ դասարանը պետք է միանգամից մուտքագրվի՝ հիմնվելով մուտքագրման վրա։
Սա սկզբունքորեն լավ է աշխատում, բայց եթե դուք ունեք բազմաթիվ տարբեր հնարավոր մուտքեր (շատ տարրեր enum-ում կամ միգուցե մուտքը մի քանի տարբեր արժեքների համակցություն է), այն կարող է դառնալ հոգնեցուցիչ եւ սխալների հակում պահպանելու համար, եւ դիզայնը միշտ ունի այն թերությունը, որը դուք պետք է փոխեք, ասում են կառուցման մեթոդը, եթե երբեւէ ավելացնեք նոր ենթադաս կամ կատարեք փոփոխություններ, որոնց հիման վրա պետք է օգտագործվի ենթաբաժինը:
Բարեբախտաբար, գոյություն ունի շատ ավելի նրբագեղ, բայց, ցավոք, նաեւ շատ ավելի քիչ հայտնի, դա անելու ձեւը, այսինքն՝ SysExtension-ի շրջանակի կիրառումը:
Այս շրջանակը օգտվում է այն հատկանիշներից, որոնք դուք կարող եք օգտագործել ձեր ենթաբաժինները զարդարելու համար, որպեսզի համակարգը կարողանա պարզել, թե որ ենթատեսակը պետք է օգտագործվի այն լուծելու համար: Դուք դեռ կարիք կունենաք կառուցման մեթոդի, բայց ճիշտ կատարելու դեպքում երբեք ստիպված չեք լինի փոխել այն նոր ենթաբաժիններ ավելացնելիս:
Եկեք նայենք երեւակայական օրինակին եւ ասենք, որ դուք պատրաստվում եք իրականացնել մի հիերարխիա, որը ինչ-որ ձեւով մշակում է, որը հիմնված է InventTrans սեղանի վրա: Որ մշակումը պետք է անել, կախված է գրանցումների StatusReceipt եւ StatusIssue- ից, ինչպես նաեւ այն բանից, թե արդյոք արձանագրությունները կապված են SalesLine, PurchLine կամ ոչ: Արդեն հիմա դուք նայում եք շատ տարբեր համադրություններ:
Հետո ասենք, որ դուք գիտեք, որ հիմա միայն մի բուռ կոմբինացիաներ պետք է ձեռք բերեք, բայց նաեւ գիտեք, որ ձեզ կխնդրեն ժամանակի ընթացքում ավելի ու ավելի շատ կոմբինացիաներ ձեռք բերել:
Եկեք այն համեմատաբար պարզ պահենք եւ ասենք, որ հիմա միայն պետք է վարեք SalesLine-ի հետ կապված գրառումները ReservPhysical-ի կամ ReservOrdered-ի StatusIssue-ի հետ, մնացած բոլոր կոմբինացիաները այժմ կարելի է անտեսել, բայց քանի որ դուք գիտեք, որ դրանք պետք է ավելի ուշ ձեռք բերեք, դուք կցանկանաք նախագծել ձեր կոդը այնպես, որ այն հեշտությամբ ելակետային լինի:
Ձեր հիերարխիան կարող է նման մի բան տեսք ունենալ հիմա.
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Այժմ, դուք կարող եք հեշտությամբ կիրառել մի մեթոդ super դասի, որը ակնթարթորեն ենթադասի վրա հիմնված է ՄոդուլInventPurchSales եւ StatusIssue enum: Բայց այդ ժամանակ դուք պետք է ամեն անգամ, երբ ավելացնեք ենթադասը, պետք է փոխեք սուպեր դասարանը, եւ դա իրականում օբյեկտ կողմնորոշված ծրագրավորման մեջ ժառանգության գաղափարը չէ։ Afterall- ը, կարիք չկա ամեն անգամ նոր batch աշխատանք ավելացնելիս փոփոխել RunBaseBatch կամ SysOperationServiceBase:
Փոխարենը, դուք կարող եք օգտվել SysExtension շրջանակից: Դա ձեզանից կպահանջի ավելացնել մեկ այլ դաս, որը պետք է երկարացնի SysAttribute- ը: Այս դասը կօգտագործվի որպես հատկություն, որով դուք կարող եք զարդարել ձեր մշակման դասերը:
Այս դասը շատ նման է այն բանին, թե ինչպես դուք կդարձնեք տվյալների պայմանագրային դաս sysOperation իրականացման համար, քանի որ այն կունենա որոշ տվյալների անդամներ եւ parm մեթոդներ այդ արժեքները ստանալու եւ սահմանելու համար:
Մեր դեպքում ClassDeclaration-ը կարող է նման տեսք ունենալ.
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Անհրաժեշտ է կատարել նոր () մեթոդ՝ տվյալների բոլոր անդամներին ակնթարթային դարձնելու համար: Եթե ցանկանում եք, որ դուք կարողանաք տալ դրանցից մի քանիսը կամ բոլորը նախնական արժեքներ, բայց ես դա չեմ արել:
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
{
}
Դուք, իհարկե, կարող եք ձեր դասերը անվանել ցանկացած ձեւով, այստեղ կարեւորն այն է, որ դուք զարդարում եք ձեր դասերը այնպիսի հատկանիշներով, որոնք համապատասխանում են, թե ինչպիսի մշակում են նրանք անում: (Բայց հիշեք, որ Դինամիկայի AX-ում կան դասի հիերարխիաների անվանման կոնվենցիաներ եւ միշտ լավ միտք է հետեւել դրանց, հնարավորության դեպքում):
Այժմ, երբ դուք զարդարել եք ձեր դասերը, որպեսզի պարզեք, թե նրանցից յուրաքանչյուրն ինչ մշակման է ենթարկվում, դուք կարող եք օգտվել SysExtension շրջանակից, որպեսզի անհրաժեշտության դեպքում միանգամից դասավորեք ենթ դասարանների օբյեկտները:
Ձեր super դասում (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() մեթոդն է: Ինչ է անում այս մեթոդը, այն է, որ այն ընդունում է հիերարխիայի սուպեր դասի անվանումը (եւ այս գերդասակարգը կարիք չունի հիերարխիայի գագաթին լինելու. դա պարզապես նշանակում է, որ միայն այս դասի երկարացնող դասերը հասանելի կլինեն) եւ ատրիբուտ օբյեկտի:
Այնուհետեւ այն վերադարձնում է դասի առարկան, որը երկարացնում է նշված սուպեր դասը եւ զարդարված է համապատասխան հատկություններով:
Ակնհայտ է, որ դուք կարող եք ավելացնել կառուցման մեթոդին այնքան լրացուցիչ հիմնավորում կամ տրամաբանություն, որքան ցանկանում եք, սակայն այստեղ կարեւոր takeaway է, որ մի անգամ իրականացված, դուք երբեք չպետք է ստիպված լինեք կրկին փոփոխել այս մեթոդը: Հիերարխիային կարող եք ավելացնել ենթաբաժիններ եւ քանի դեռ դուք համոզվեք, որ դրանք պատշաճ կերպով զարդարեք, կառուցման մեթոդը կգտնի դրանք, չնայած որ դրանք գոյություն չունեին, երբ այն գրվել է:
Իսկ ի՞նչ կարելի է ասել կատարողականի մասին: Ես անկեղծորեն չեմ փորձել չափել այն, բայց իմ ներքին զգացողությունն այն է, որ սա հավանաբար ավելի վատ է գործում, քան դասական switch statement դիզայնը: Սակայն, հաշվի առնելով, որ Dynamics AX-ում ամենաշատ կատարման խնդիրները պայմանավորված են տվյալների բազայի հասանելիությամբ, ես չափից շատ չէի անհանգստանա դրա համար:
Իհարկե, եթե դուք իրականացնում եք մի բան, որը պահանջելու է, որ հազարավոր օբյեկտներ արագ ստեղծվեն, դուք կարող եք ավելի մանրամասն հետազոտել, բայց դասական դեպքերում, երբ դուք պարզապես ակնթարթում եք մեկ առարկա ինչ-որ երկարատեւ մշակում կատարելու համար, ես կասկածում եմ, որ դա նշանակություն կունենա: Բացի այդ, հաշվի առնելով իմ անհանգստացնող թեյավճարը (հաջորդ պարբերությունը), երեւում է, որ SysExtension-ի շրջանակը հենվում է caching-ի վրա, ուստի վազող համակարգում ես կասկածում եմ, որ այն ունի զգալի կատարողական հարված: Troubleshooting: Եթե կառուցման մեթոդը չի գտնում ձեր ենթաբաժինները, չնայած դուք համոզված եք, որ դրանք ճիշտ են զարդարված, դա կարող է լինել caching խնդիր: Փորձեք մաքրել caches եւ՛ հաճախորդի, եւ՛ սերվերի վրա: Պետք չէ իրականում վերսկսել AOS-ը, բայց դա կարող է լինել վերջին միջոցը: