Gamit ang SysExtension Framework para Malaman Aling Subclass ang I-instantiate sa Dynamics AX 2012
Nai-publish: Marso 19, 2025 nang 9:25:45 PM UTC
Inilalarawan ng artikulong ito kung paano gamitin ang maliit na kilalang SysExtension framework sa Dynamics AX 2012 at Dynamics 365 for Operations upang i-instantiate ang mga sub class batay sa mga dekorasyon ng attribute, na nagbibigay-daan para sa isang madaling mapalawak na disenyo ng isang processing class hierarchy.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Ang impormasyon sa post na ito ay batay sa Dynamics AX 2012 R3. Ito ay maaaring o maaaring hindi wasto para sa iba pang mga bersyon. (Update: Maaari kong kumpirmahin na ang impormasyon sa artikulong ito ay wasto din para sa Dynamics 365 for Operations)
Kapag nagpapatupad ng mga klase sa pagpoproseso sa Dynamics AX, madalas kang nahaharap sa paggawa ng hierarchy ng klase kung saan ang bawat subclass ay tumutugma sa isang halaga ng enum o may ilang iba pang data coupling. Ang isang klasikong disenyo ay magkakaroon ng isang paraan ng pagbuo sa super class, na mayroong switch na tumutukoy kung aling klase ang i-instantiate batay sa input.
Ito ay gumagana nang maayos sa prinsipyo, ngunit kung mayroon kang maraming iba't ibang mga posibleng input (maraming mga elemento sa isang enum o marahil ang input ay isang kumbinasyon ng maraming iba't ibang mga halaga), maaari itong maging nakakapagod at madaling mag-error upang mapanatili at ang disenyo ay palaging may kawalan na kakailanganin mong baguhin ang nasabing construct method kung sakaling magdagdag ka ng isang bagong subclass o gumawa ng mga pagbabago sa kung aling subclass ang dapat gamitin batay sa kung aling input.
Sa kabutihang palad, mayroong isang mas eleganteng, ngunit sa kasamaang-palad ay hindi gaanong kilala, na paraan ng paggawa nito, lalo na sa pamamagitan ng paggamit ng SysExtension framework.
Sinasamantala ng framework na ito ang mga attribute na maaari mong gamitin para palamutihan ang iyong mga sub class para magawa ng system na malaman kung aling sub class ang dapat gamitin para sa paghawak ng kung ano. Kakailanganin mo pa rin ang isang paraan ng pagbuo, ngunit kung nagawa nang tama, hindi mo na ito kailangang baguhin kapag nagdaragdag ng mga bagong sub class.
Tingnan natin ang isang haka-haka na halimbawa at sabihin na magpapatupad ka ng hierarchy na gumagawa ng ilang uri ng pagproseso batay sa talahanayan ng InventTrans. Aling pagpoproseso ang gagawin ay nakasalalay sa StatusReceipt at StatusIssue ng mga tala, pati na rin kung ang mga tala ay nauugnay sa SalesLine, PurchLine o wala. Sa ngayon, tumitingin ka sa maraming iba't ibang kumbinasyon.
Sabihin natin na alam mo na sa ngayon kailangan mo lang hawakan ang isang maliit na bilang ng mga kumbinasyon, ngunit alam mo rin na hihilingin sa iyo na makayanan ang higit pang mga kumbinasyon sa paglipas ng panahon.
Panatilihin natin itong medyo simple at sabihin na sa ngayon kailangan mo lang pangasiwaan ang mga record na nauugnay sa SalesLine na may StatusIssue of ReservPhysical o ReservOrdered, lahat ng iba pang kumbinasyon ay maaaring balewalain sa ngayon, ngunit dahil alam mong kakailanganin mong pangasiwaan ang mga ito sa ibang pagkakataon, gugustuhin mong idisenyo ang iyong code sa paraang ginagawa itong madaling mapalawak.
Maaaring ganito ang hitsura ng iyong hierarchy sa ngayon:
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Ngayon, madali mong maipapatupad ang isang paraan sa super class na nagpapakilala ng isang subclass batay sa isang ModuleInventPurchSales at isang StatusIssue enum. Ngunit kakailanganin mong baguhin ang super class sa tuwing magdadagdag ka ng sub class, at hindi talaga iyon ang ideya ng pamana sa object-oriented na programming. Kung tutuusin, hindi mo kailangang baguhin ang RunBaseBatch o SysOperationServiceBase tuwing magdadagdag ka ng bagong batch job.
Sa halip, maaari mong gamitin ang SysExtension framework. Kakailanganin ka nitong magdagdag ng isa pang klase, na kailangang palawigin ang SysAttribute. Gagamitin ang klase na ito bilang katangian na maaari mong palamutihan ang iyong mga klase sa pagproseso.
Ang klase na ito ay halos kapareho sa kung paano ka gagawa ng klase ng kontrata ng data para sa pagpapatupad ng SysOperation, dahil magkakaroon ito ng ilang miyembro ng data at mga pamamaraan ng parm para sa pagkuha at pagtatakda ng mga halagang iyon.
Sa aming kaso, ang ClassDeclaration ay maaaring magmukhang ganito:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Kailangan mong gumawa ng bagong() na pamamaraan para sa pag-instantiate ng lahat ng miyembro ng data. Kung nais mo maaari kang magbigay ng ilan o lahat ng mga ito ng mga default na halaga, ngunit hindi ko pa nagawa iyon.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
At dapat mo ring ipatupad ang isang paraan ng parm para sa bawat miyembro ng data, ngunit tinanggal ko ang mga iyon dito dahil sigurado akong alam mo kung paano gawin iyon - kung hindi, ituring natin itong isang ehersisyo ;-)
Magagamit mo na ngayon ang iyong attribute class para palamutihan ang bawat isa sa iyong processing classes. Halimbawa, ang mga deklarasyon ng klase ay maaaring magmukhang ganito:
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
{
}
Siyempre, maaari mong pangalanan ang iyong mga klase sa anumang paraan na gusto mo, ang mahalagang bahagi dito ay palamutihan mo ang iyong mga klase ng mga katangian na tumutugma sa kung anong uri ng pagproseso ang ginagawa nila. (Ngunit tandaan na mayroong mga kombensiyon sa pagbibigay ng pangalan para sa mga hierarchy ng klase sa Dynamics AX at palaging magandang ideya na sundin ang mga iyon, kung maaari).
Ngayong pinalamutian mo na ang iyong mga klase upang matukoy kung anong uri ng pagproseso ang ginagawa ng bawat isa sa kanila, maaari mong samantalahin ang SysExtension framework upang ma-instantiate ang mga bagay ng mga sub class kung kinakailangan.
Sa iyong super class (MyProcessor), maaari kang magdagdag ng paraan ng pagbuo tulad nito:
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;
}
Ang talagang kawili-wiling bahagi - at talagang ang bagay (paumanhin ang pun) ng buong post na ito - ay ang getClassFromSysAttribute() na pamamaraan sa SysExtensionAppClassFactory na klase. Ang ginagawa ng pamamaraang ito ay tinatanggap nito ang pangalan ng super class ng isang hierarchy (at ang super class na ito ay hindi kailangang nasa tuktok ng hierarchy; nangangahulugan lamang ito na ang mga klase lamang na nagpapalawak sa klase na ito ang magiging karapat-dapat) at isang attribute object.
Pagkatapos ay ibinabalik nito ang isang bagay ng isang klase na nagpapalawak sa tinukoy na super class at pinalamutian ng isang kaukulang katangian.
Malinaw na maaari kang magdagdag ng higit pang pagpapatunay o lohika sa paraan ng pagtatayo hangga't gusto mo, ngunit ang mahalagang takeaway dito ay kapag ipinatupad na, hindi mo na kailangang baguhin muli ang pamamaraang ito. Maaari kang magdagdag ng mga sub class sa hierarchy at hangga't siguraduhin mong palamutihan ang mga ito nang naaangkop, hahanapin sila ng paraan ng construct kahit na wala ang mga ito noong isinulat ito.
Paano naman ang performance? Sa totoo lang ay hindi ko pa sinubukang i-benchmark ito, ngunit ang pakiramdam ko ay malamang na ito ay gumaganap nang mas masahol kaysa sa klasikong disenyo ng switch statement. Gayunpaman, kung isasaalang-alang na ang karamihan sa mga isyu sa pagganap sa Dynamics AX ay sanhi ng pag-access sa database, hindi ako mag-aalala tungkol dito.
Siyempre, kung nagpapatupad ka ng isang bagay na mangangailangan ng libu-libong mga bagay na malikha nang mabilis, maaaring gusto mong mag-imbestiga pa, ngunit sa mga klasikong kaso kung saan nag-i-instantiate ka lang ng isang bagay upang gumawa ng ilang mahabang pagproseso, duda ako na mahalaga ito. Gayundin, kung isasaalang-alang ang aking tip sa pag-troubleshoot (susunod na talata), lumilitaw na ang SysExtension framework ay umaasa sa pag-cache, kaya sa isang tumatakbong sistema ay nagdududa ako na mayroon itong makabuluhang hit sa pagganap.
Pag-troubleshoot: Kung hindi mahanap ng paraan ng construct ang iyong mga sub class kahit na sigurado kang pinalamutian nang tama ang mga ito, maaaring ito ay isang problema sa pag-cache. Subukang i-clear ang mga cache sa parehong client at server. Hindi dapat kailanganing aktwal na i-restart ang AOS, ngunit maaaring ito na ang huling paraan.