Menggunakan Rangka Kerja SysExtension untuk Mengetahui Subkelas mana yang hendak dibuat dalam Dynamics AX 2012
Diterbitkan: 19 Mac 2025 pada 9:25:32 PTG UTC
Artikel ini menerangkan cara menggunakan rangka kerja SysExtension yang kurang dikenali dalam Dynamics AX 2012 dan Dynamics 365 for Operations untuk membuat contoh subkelas berdasarkan hiasan atribut, membolehkan reka bentuk hierarki kelas pemprosesan yang boleh diperluas dengan mudah.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Maklumat dalam siaran ini adalah berdasarkan Dynamics AX 2012 R3. Ia mungkin atau mungkin tidak sah untuk versi lain. (Kemas kini: Saya boleh mengesahkan bahawa maklumat dalam artikel ini juga sah untuk Dynamics 365 for Operations)
Apabila melaksanakan kelas pemprosesan dalam Dynamics AX, anda sering berhadapan dengan mencipta hierarki kelas di mana setiap subkelas sepadan dengan nilai enum atau mempunyai beberapa gandingan data lain. Reka bentuk klasik kemudiannya mempunyai kaedah binaan dalam kelas super, yang mempunyai suis yang menentukan kelas mana yang hendak digunakan berdasarkan input.
Ini berfungsi dengan baik pada dasarnya, tetapi jika anda mempunyai banyak kemungkinan input yang berbeza (banyak elemen dalam enum atau mungkin input adalah gabungan beberapa nilai yang berbeza), ia boleh menjadi membosankan dan terdedah kepada ralat untuk dikekalkan dan reka bentuk sentiasa mempunyai kelemahan yang anda perlukan untuk mengubah suai kaedah binaan tersebut jika anda pernah menambah subkelas baharu atau membuat perubahan pada subkelas yang harus digunakan berdasarkan input mana.
Nasib baik, terdapat cara yang lebih elegan, tetapi malangnya juga kurang dikenali, cara melakukan ini, iaitu dengan menggunakan rangka kerja SysExtension.
Rangka kerja ini mengambil kesempatan daripada atribut yang boleh anda gunakan untuk menghiasi subkelas anda untuk menjadikan sistem dapat mengetahui subkelas yang harus digunakan untuk mengendalikan apa. Anda masih memerlukan kaedah binaan, tetapi jika dilakukan dengan betul, anda tidak perlu mengubah suainya apabila menambah sub kelas baharu.
Mari lihat contoh khayalan dan katakan bahawa anda akan melaksanakan hierarki yang melakukan beberapa jenis pemprosesan berdasarkan jadual InventTrans. Pemprosesan yang perlu dilakukan bergantung pada StatusReceipt dan StatusIssue rekod, serta sama ada rekod berkaitan dengan SalesLine, PurchLine atau tidak. Kini, anda sedang melihat banyak kombinasi yang berbeza.
Katakan anda tahu bahawa buat masa ini anda hanya perlu mengendalikan segelintir kombinasi, tetapi anda juga tahu bahawa anda akan diminta untuk dapat mengendalikan lebih banyak kombinasi dari semasa ke semasa.
Biarkan ia agak mudah dan katakan bahawa buat masa ini anda hanya perlu mengendalikan rekod yang berkaitan dengan SalesLine dengan StatusIssue of ReservPhysical atau ReservOrdered, semua kombinasi lain boleh diabaikan buat masa ini, tetapi kerana anda tahu anda perlu mengendalikannya kemudian, anda perlu mereka bentuk kod anda dengan cara yang menjadikannya mudah diperluaskan.
Hierarki anda mungkin kelihatan seperti ini buat masa ini:
- MyProcessor
- MyProcessor_Sales
- MyProcessor_Sales_Reserved
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Kini, anda boleh dengan mudah melaksanakan kaedah dalam kelas super yang membuat contoh subkelas berdasarkan ModuleInventPurchSales dan enum StatusIssue. Tetapi anda kemudiannya perlu mengubah suai kelas super setiap kali anda menambah sub kelas, dan itu bukanlah idea pewarisan dalam pengaturcaraan berorientasikan objek. Lagipun, anda tidak perlu mengubah suai RunBaseBatch atau SysOperationServiceBase setiap kali anda menambah kerja kelompok baharu.
Sebaliknya, anda boleh menggunakan rangka kerja SysExtension. Itu memerlukan anda menambah kelas lain, yang perlu melanjutkan SysAttribute. Kelas ini akan digunakan sebagai atribut yang anda boleh menghiasi kelas pemprosesan anda.
Kelas ini sangat serupa dengan cara anda membuat kelas kontrak data untuk pelaksanaan SysOperation, kerana ia akan mempunyai beberapa ahli data dan kaedah parm untuk mendapatkan dan menetapkan nilai tersebut.
Dalam kes kami, ClassDeclaration mungkin kelihatan seperti ini:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Anda perlu membuat kaedah baru() untuk membuat instantiating semua ahli data. Jika anda mahu anda boleh memberikan beberapa atau kesemuanya nilai lalai, tetapi saya tidak melakukannya.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Dan anda juga harus melaksanakan kaedah parm untuk setiap ahli data, tetapi saya telah meninggalkannya di sini kerana saya pasti anda tahu cara melakukannya - jika tidak, mari anggap ia sebagai latihan ;-)
Kini anda boleh menggunakan kelas atribut anda untuk menghiasi setiap kelas pemprosesan anda. Sebagai contoh, pengisytiharan kelas boleh kelihatan seperti ini:
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
{
}
Anda sudah tentu boleh menamakan kelas anda dengan cara yang anda mahu, bahagian penting di sini ialah anda menghiasi kelas anda dengan atribut yang sepadan dengan jenis pemprosesan yang mereka lakukan. (Tetapi perlu diingat bahawa terdapat konvensyen penamaan untuk hierarki kelas dalam Dynamics AX dan selalunya idea yang baik untuk mengikutinya, jika boleh).
Memandangkan anda telah menghiasi kelas anda untuk mengenal pasti jenis pemprosesan yang dilakukan oleh setiap kelas, anda boleh memanfaatkan rangka kerja SysExtension untuk menjadikan objek subkelas mengikut keperluan.
Dalam kelas super anda (MyProcessor), anda boleh menambah kaedah binaan seperti ini:
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;
}
Bahagian yang benar-benar menarik - dan benar-benar objek (maafkan kata-kata) keseluruhan siaran ini - ialah kaedah getClassFromSysAttribute() dalam kelas SysExtensionAppClassFactory. Apa yang dilakukan oleh kaedah ini ialah ia menerima nama kelas super hierarki (dan kelas super ini tidak perlu berada di bahagian atas hierarki; ini bermakna hanya kelas yang melanjutkan kelas ini akan layak) dan objek atribut.
Ia kemudian mengembalikan objek kelas yang memanjangkan kelas super yang ditentukan dan dihiasi dengan atribut yang sepadan.
Anda jelas boleh menambah lebih banyak pengesahan atau logik pada kaedah konstruk seperti yang anda mahu, tetapi perkara penting di sini ialah sebaik sahaja dilaksanakan, anda tidak perlu mengubah suai kaedah ini lagi. Anda boleh menambah sub kelas pada hierarki dan selagi anda memastikan untuk menghiasinya dengan sewajarnya, kaedah bina akan menemuinya walaupun ia tidak wujud semasa ia ditulis.
Bagaimana pula dengan prestasi? Sejujurnya saya tidak cuba menanda arasnya, tetapi perasaan saya ialah ini mungkin berprestasi lebih teruk daripada reka bentuk pernyataan suis klasik. Walau bagaimanapun, memandangkan setakat ini kebanyakan isu prestasi dalam Dynamics AX disebabkan oleh akses pangkalan data, saya tidak akan terlalu risau mengenainya.
Sudah tentu, jika anda melaksanakan sesuatu yang memerlukan beribu-ribu objek untuk dibuat dengan cepat, anda mungkin mahu menyiasat lebih lanjut, tetapi dalam kes klasik di mana anda hanya membuat seketika satu objek untuk melakukan pemprosesan yang panjang, saya ragu ia akan menjadi masalah. Selain itu, mempertimbangkan petua penyelesaian masalah saya (perenggan seterusnya), nampaknya rangka kerja SysExtension bergantung pada caching, jadi dalam sistem yang sedang berjalan saya ragu ia mempunyai prestasi yang ketara.
Penyelesaian masalah: Jika kaedah binaan tidak menjumpai subkelas anda walaupun anda pasti mereka dihias dengan betul, ini mungkin masalah caching. Cuba kosongkan cache pada klien dan pelayan. Ia tidak semestinya perlu untuk memulakan semula AOS, tetapi ia mungkin pilihan terakhir.