SysExtension Framework-un istifadə edərək Dynamics AX 2012-də Hansı Subklass-ın aniləşdirmək lazım olduğunu öyrənin
Nəşr olundu: 16 fevral 2025 at 00:29:32 UTC
Bu məqalədə Dynamics AX 2012-də az bilinən SysExtension framework və Dynamics 365 for Operations atribut bəzəkləri əsasında alt siniflərin aniləşdirilməsi üçün necə istifadə edilməsi təsvir edilir. Bu, prosessinq sinif iyerarxiyasının asanlıqla genişləndirilməsi üçün imkan verir.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Bu postdakı məlumatlar Dynamics AX 2012 R3 əsasında hazırlanıb. Digər versiyalar üçün də keçərli ola bilər və ya olmaya bilər. (Update: Bu məqalədəki məlumatların Əməliyyat üçün Dynamics 365 üçün də keçərli olduğunu təsdiq edə bilərəm)
Dynamics AX-də işlənmə siniflərini həyata keçirərkən, çox vaxt hər alt sinifin bir enum dəyərinə uyğun gəldiyi və ya bəzi digər məlumat kuplingləri olduğu bir sinif iyerarxiyası yaratmaqla qarşılaşırsınız. Klassik dizayn bundan sonra super sinifdə inşa metoduna malik olmaq lazımdır. Bu üsul girişə əsasən hansı sinfin aniləşdirməsini müəyyən edən keçidə malikdir.
Bu prinsipcə yaxşı işləyir, amma əgər sizdə bir çox müxtəlif mümkün girişlər varsa (bir çox elementlər bir enumda və ya bəlkə də giriş bir neçə müxtəlif dəyərlərin birləşməsidir), bu, tıssız və xətaya meylli ola bilər ki, onu qoruyub saxlayasınız və dizayn həmişə əlverişsizliyə malikdir ki, əgər siz nə vaxtsa yeni altklass əlavə etsəniz və ya hansı altklass hansı giriş əsasında istifadə olunmalıdır dəyişikliklər etsəniz, deyilən inşa metodunu dəyişdirmək lazım olacaq.
Xoşbəxtlikdən, çox daha zərif bir şey var, amma təəssüf ki, çox az bilinən də, bunu etmə üsulu, yəni SysExtension framework-dən istifadə etməklə.
Bu çərçivə alt siniflərinizi bəzəmək üçün istifadə edə biləcəyiniz xüsusiyyətlərdən yararlanaraq sistem nəyin öhdəsindən gəlmək üçün hansı alt sinifdən istifadə edilməli olduğunu müəyyən edə bilir. Sizə hələ də konstruktiv üsul lazım olacaq, lakin düzgün yerinə yetirilsə, yeni alt siniflər əlavə edərkən onu heç vaxt dəyişdirmək lazım olmayacaq.
Xəyali bir nümunəyə baxaq və inventTrans tablosuna əsasən bir növ prosessinq edən bir iyerarxiya həyata keçirəcəyinizi söyləyək. Hansı işlənilmə sənədlərin StatusReceipt və StatusIssue-dan, eləcə də qeydlərin SalesLine, PurchLine və ya heç biri ilə bağlı olub-olmamasından asılıdır. Artıq indi bir çox müxtəlif kombinasiyalara baxırsınız.
Sonra deyək ki, indidən bilirsiniz ki, kombinasiyaların yalnız bir ovucunun öhdəsindən gəlmək lazımdır. Amma siz də bilirsiniz ki, sizdən vaxt keçdikcə daha çox kombinasiyaların öhdəsindən gəlməyiniz xahiş olunacaq.
Bunu nisbətən sadə saxlayaq və deyək ki, indi üçün yalnız SalesLine ilə bağlı qeydləri "ReservPhysical" və ya "ReservOrdered"in "Statusissue" ilə həll etmək lazımdır. Bütün digər kombinasiyalara indidən diqqət yetirmək olar. Lakin sonradan onların öhdəsindən gəlmək məcburiyyətində olacağınızı bildiyiniz üçün, kodunuzu asanlıqla genişlədiləcək şəkildə dizayn etmək istəyəcəksiniz.
Sizin iyerarxiyanız indilik belə görünə bilər:
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
İndi, moduleInventPurchSales və statusIssue enum əsasında subklas aniləşdirən super sinifdə asanlıqla bir metodu tətbiq edə bilərsiniz. Amma bundan sonra hər dəfə alt sinif əlavə etdikdə super sinfi dəyişdirmək lazım gələcək. Əslində obyekt yönümlü proqramlaşdırmada miras ideyası bu deyil. Afterall, hər dəfə yeni toplu iş əlavə etdikdə RunBaseBatch və ya SysOperationServiceBase-də dəyişiklik etməyə ehtiyac yoxdur.
Bunun əvəzinə SysExtension çərçivəsindən istifadə edə bilərsiniz. Bunun üçün başqa bir sinif əlavə etmək lazım gələcək. SysAttribute-u uzatmaq lazımdır. Bu sinif, prosessinq siniflərinizi bəzəyə biləcəyiniz atribut kimi istifadə olunacaq.
Bu sinif, SysOperation tətbiqi üçün bir data müqavilə sinifini necə düzəldəcəyinizə çox bənzəyir. Belə ki, bu dəyərlər əldə etmək və təyin etmək üçün bəzi məlumat üzvləri və parm metodları olacaq.
Bizim halda ClassDeclaration belə görünə bilər:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Bütün məlumat üzvlərinin aniləşdirilməsi üçün yeni() metod hazırlamaq lazımdır. Əgər istəsəniz, onlardan bəzilərini və ya hamısını default dəyərlərə verə bilərsiniz, amma mən bunu etməmişəm.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Və siz hər bir məlumat üzvü üçün parm metodunu da tətbiq etməlisiniz. Amma mən əminəm ki, bunu necə etməyi bilirsiniz deyə, buradakıları buraxmışam - əks halda, gəlin bunu məşq hesab edək ;-)
İndi isə hər bir işlənmə sinifinizi bəzəmək üçün atribut sinifinizi istifadə edə bilərsiniz. Məsələn, sinif bəyannamələri belə görünə bilər:
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
{
}
Əlbəttə ki, istədiyiniz şəkildə siniflərinizə ad verə bilərsiniz. Burada vacib olan hissə, siniflərinizi hansı növ işlənmələrinə uyğun olan xüsusiyyətlərlə bəzəməyinizdir. (Amma yadda saxlayın ki, Dynamics AX-də sinif iyerarxiyaları üçün adlandırma konvensiyaları var və bunları izləmək həmişə yaxşı fikirdir, mümkünsə).
İndi siz siniflərinizi bəzəyən və onların hər birinin hansı işlənməni etdiyini müəyyən etdiyiniz üçün, SysExtension çərçivəsindən yararlanaraq, lazım gəldikdə alt siniflərin obyektlərini aniləşdirmək olar.
Super sinifinizdə (MyProcessor) belə bir inşa metodu əlavə edə bilərsiniz:
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;
}
Həqiqətən maraqlı hissəsi - və həqiqətən bütün bu postun obyekt (pardon the pun) - SysExtensionAppClassFactory sinfində getClassFromSysAttribute() metodudur. Bu metodun gördüyü iş odur ki, o, iyerarxiyanın super sinfinin adını (və bu super sinfin iyerarxiyanın başında olması lazım deyil; sadəcə olaraq bu sinifi uzadan yalnız siniflərin yararlı olacağı deməkdir) və atribut obyektinin adını qəbul edir.
Sonra o, müəyyən olunmuş super sinfi genişləndirən və müvafiq atributla bəzədilmiş sinifin obyektini qaytarır.
Aydındır ki, konstruktor metoduna istədiyiniz qədər daha çox təsdiq və ya məntiq əlavə edə bilərsiniz. Amma burada vacib olan götürmə budur ki, həyata keçiriləndən sonra bir daha bu metodu dəyişdirmək lazım deyil. Siz iyerarxiyaya alt siniflər əlavə edə bilərsiniz və nə qədər ki, onları layiqincə bəzəmək üçün əminsiniz, inşa üsulu yazılanda mövcud olmasa da, onları tapacaq.
Bəs ifa etmək barədə nə demək? Düzünü desəm, bunu benchmark etməyə cəhd etməmişəm, amma bağırsaq hissim odur ki, bu, çox güman ki , klassik switch bəyanat dizaynından daha betər performans göstərir. Lakin nəzərə alsaq ki, indiyə qədər Dynamics AX-də ən çox performans məsələləri verilənlər bazasına girişdən qaynaqlanır, mən buna görə çox narahat olmazdım.
Təbii ki, minlərlə obyektin tez bir zamanda yaradılmasını tələb edəcək bir şeyi həyata keçirirsinizsə, daha dərindən araşdırmaq istəyə bilərsiniz. Ancaq bir neçə uzun prosessinq etmək üçün sadəcə bir obyektin ani olaraq başladığınız klassik işlərdə bunun əhəmiyyət kəsb edəcəyinə şübhə edirəm. Həmçinin, mənim troubleshooting ucumu (növbəti abzas) nəzərə alsaq, görünür ki, SysExtension framework caching-ə əsaslanır, buna görə də qaçış sistemində onun əhəmiyyətli performans hitinə malik olduğuna şübhə edirəm. Troubleshooting: Əgər inşa metodu sizin alt siniflərinizi düzgün bəzədilməsinə əmin olsanız belə tapmırsa, bu, bir cəzbedici problem ola bilər. Həm klientdə, həm də vericidə olan önbelleği təmizlə Əslində AOS-a yenidən başlamaq lazım deyil, amma son çarə ola bilər.