Notkun SysExtension ramma til að finna út hvaða undirflokk á að stofna í Dynamics AX 2012
Birt: 19. mars 2025 kl. 21:25:26 UTC
Þessi grein lýsir því hvernig á að nota lítt þekkta SysExtension ramma í Dynamics AX 2012 og Dynamics 365 for Operations til að stofna undirflokka byggða á eigindaskreytingum, sem gerir kleift að stækka vinnsluflokkastigveldi auðveldlega.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Upplýsingarnar í þessari færslu byggja á Dynamics AX 2012 R3. Þær kunna að vera giltar eða ekki fyrir aðrar útgáfur. (Uppfærsla: Ég get staðfest að upplýsingarnar í þessari grein eru einnig giltar fyrir Dynamics 365 for Operations)
Við innleiðingu á úrvinnsluflokkum í Dynamics AX stendur maður oft frammi fyrir því að búa til flokkhierarkíu þar sem hver undirflokkur samsvarar enum-gildi eða hefur einhvers konar gögnatengingu. Klassísk hönnun er að hafa þá aðferð sem byggir á yfirflokknum, sem hefur valkost sem ákvarðar hvaða flokkur á að stofna út frá inntakinu.
Þetta virkar vel í meginatriðum, en ef þú hefur mörg mismunandi möguleg inntök (marga þætti í enum eða kannski er inntakið samsetning af mörgum mismunandi gildum) getur það orðið þreytandi og villuþýtt að viðhalda og hönnunin hefur alltaf ókostinn að þú þarft að breyta viðkomandi aðferð ef þú bætir við nýjum undirflokki eða breytir því hvaða undirflokkur á að vera notaður út frá hvaða inntaki.
Sem betur fer er til mun fínni, en miður oft minna þekkt, leið til að gera þetta, nefnilega með því að nota SysExtension ramma.
Þessi rammi nýtir sér eiginleika sem þú getur notað til að skreyta undirflokkana þína til að gera kerfið fær um að átta sig á hvaða undirflokkur á að vera notaður til að meðhöndla hvað. Þú munt ennþá þurfa að hafa aðferð til að búa til hluti, en ef þetta er gert rétt, þarftu aldrei að breyta henni þegar þú bætir við nýjum undirflokkum.
Við skulum skoða ímyndaðan dæmi og segja að þú sért að innleiða hierarkíu sem framkvæmir einhvers konar úrvinnslu byggt á InventTrans töflunni. Hvaða úrvinnsla á að gera fer eftir StatusReceipt og StatusIssue færslunum, sem og hvort færslurnar tengjast SalesLine, PurchLine eða hvorugum. Þegar þetta er skoðað, ertu þegar að skoða mörg mismunandi samsetningar.
Við skulum segja að þú vitir að fyrir þessa stundina þarftu aðeins að meðhöndla handfylli af samsetningum, en þú veist líka að þú verður beðinn um að geta meðhöndlað fleiri og fleiri samsetningar með tímanum.
Við skulum halda því einfalt og segja að fyrir þessa stundina þarftu aðeins að meðhöndla færslur tengdar SalesLine með StatusIssue sem er ReservPhysical eða ReservOrdered, allar aðrar samsetningar má útrýma fyrir þessa stundina, en þar sem þú veist að þú verður að meðhöndla þær síðar, viltu hanna kóðann þinn á þann hátt að hann sé auðvelt að stækka.
Hierarkían þín gæti litið svona út fyrir þessa stundina:
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Þú getur auðveldlega innleitt aðferð í yfirflokki sem stofnar undirflokk út frá ModuleInventPurchSales og StatusIssue enum. En þá þarftu að breyta yfirflokki í hvert skipti sem þú bætir við undirflokki, og það er ekki raunverulega hugmyndin með erfðafræði í hlutbundinni forritun. Eftir allt saman þarftu ekki að breyta RunBaseBatch eða SysOperationServiceBase í hvert skipti sem þú bætir við nýju batch vinnslu.
Í staðinn geturðu nýtt SysExtension ramman. Það mun krefjast þess að þú bætir við öðrum flokki sem þarf að stækka SysAttribute. Þessi flokkur verður notaður sem eiginleikinn sem þú getur skreytt úrvinnsluflokkana þína með.
Þessi flokkur er mjög lík því hvernig þú myndir búa til gögnasamningaflokk fyrir SysOperation útfærslu, þar sem hann mun hafa einhverja gagnablokkir og aðferð sem hægt er að nota til að fá og stilla þessi gildi.
Í okkar tilfelli getur ClassDeclaration litið svona út:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Þú þarft að búa til new() aðferð til að stofna allar gagnablokkir. Ef þú vilt geturðu gefið einhverjum eða öllum þeim sjálfgefnar gildi, en ég hef ekki gert það.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Og þú ættir einnig að innleiða parm aðferð fyrir hverja gagnablokk, en ég hef sleppt þeim hér þar sem ég er viss um að þú vitir hvernig á að gera það - annars, við skulum líta á það sem æfingu ;-)
Nú getur þú notað eiginleikaflokkinn þinn til að skreyta hvern úrvinnsluflokk. Til dæmis gætu flokksyfirlýsingarnar litið svona út:
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
{
}
Þú getur auðvitað nafnsett flokkana þína hvernig sem þú vilt, það sem skiptir máli hér er að þú skreytir flokkana þína með eiginleikum sem samsvara hvaða úrvinnslu þeir framkvæma. (En mundu að það eru nafngiftarreglur fyrir flokkhierarkíur í Dynamics AX og það er alltaf góð hugmynd að fylgja þeim, ef mögulegt er).
Nú þegar þú hefur skreytt flokkana þína til að bera kennsl á hvaða úrvinnslu hver þeirra framkvæmir, getur þú nýtt SysExtension ramman til að stofna hluti af undirflokkum eftir þörfum.
Í yfirflokki þínum (MyProcessor), getur þú bætt við aðferð sem byggir á þessari uppbyggingu:
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;
}
Það sem er virkilega áhugavert - og í raun fyrsti (afsakið orðaleikinn) hlutinn í þessari færslu - er getClassFromSysAttribute() aðferðin í SysExtensionAppClassFactory klasanum. Það sem þessi aðferð gerir er að hún tekur við nafni yfirstillingar í stigveldinu (og þessi yfirstilling þarf ekki að vera á toppi stigveldisins; það þýðir einfaldlega að aðeins klasar sem framlengja þennan klasa verða hæfir) og eiginleikja-objekti.
Hún skilar síðan objecti af klasa sem framlengir tiltekna yfirstillingu og er skreyttur með samsvarandi eiginleika.
Þú getur auðvitað bætt við alls konar frekari staðfestingu eða rökfræði í construct aðferðina eins og þú vilt, en mikilvægi ábendingin hér er að þegar hún er framkvæmd, ættir þú aldrei að þurfa að breyta þessari aðferð aftur. Þú getur bætt við undirkösum í stigveldið og svo lengi sem þú tryggir að skreyta þá rétt, mun construct aðferðin finna þá þótt þeir hafi ekki verið til þegar hún var skrifuð.
Hvað með frammistöðu? Ég hef reyndar ekki reynt að mæla hana, en það sem mér finnst er að þetta eflaust virki verr en klassíska switch setningin. Hins vegar, með hliðsjón af því að flest frammistöðuvandamál í Dynamics AX eru vegna gagnagrunns aðgangs, væri ég ekki of mikið að hafa áhyggjur af því.
Auðvitað, ef þú ert að útfæra eitthvað sem mun krefjast þess að þúsundir objekta verði búin til hratt, þá gætir þú viljað rannsaka það frekar, en í þeim klassísku tilvikum þar sem þú býrð bara til eitt object til að gera langa útfærslu, þá efast ég um að það muni skipta máli. Einnig, með hliðsjón af ráðleggingunum mínum um villuleit (næsti málsgrein), virðist SysExtension ramma vera háður cacha, þannig að í keyrandi kerfi efast ég um að það hafi mikil áhrif á frammistöðu.
Villuleit: Ef construct aðferðin finnur ekki undirkosurnar þínar þó þú sért viss um að þær séu skreyttar rétt, gæti það verið caching vandamál. Reyndu að hreinsa cacha bæði á viðskiptavini og þjóninum. Það ætti ekki að vera nauðsynlegt að endurræsa AOS, en það gæti verið síðasti úrræðið.