Χρήση του πλαισίου SysExtension για να μάθετε ποια δευτερεύουσα κλάση για να ξεκινήσετε στο Dynamics AX 2012
Δημοσιεύθηκε: 16 Φεβρουαρίου 2025 στις 12:25:37 π.μ. UTC
Αυτό το άρθρο περιγράφει τον τρόπο χρήσης του ελάχιστα γνωστού πλαισίου SysExtension στο Dynamics AX 2012 και Dynamics 365 for Operations για τη δημιουργία υποκλάσεων με βάση διακοσμήσεις χαρακτηριστικών, επιτρέποντας μια εύκολα επεκτάσιμη σχεδίαση μιας ιεραρχίας κλάσης επεξεργασίας.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Οι πληροφορίες σε αυτήν την καταχώρηση βασίζεται στο Dynamics AX 2012 R3. Μπορεί να ισχύει ή να μην ισχύει για άλλες εκδόσεις. (Ενημέρωση: Μπορώ να επιβεβαιώσω ότι οι πληροφορίες σε αυτό το άρθρο ισχύουν επίσης για το Dynamics 365 for Operations)
Κατά την υλοποίηση κλάσεων επεξεργασίας στο Dynamics AX, συχνά αντιμετωπίζετε τη δημιουργία μιας ιεραρχίας κλάσεων στην οποία κάθε υποκλάση αντιστοιχεί σε μια τιμή enum ή έχει κάποια άλλη σύζευξη δεδομένων. Ένας κλασικός σχεδιασμός είναι να έχετε στη συνέχεια μια μέθοδο κατασκευής στην σούπερ κατηγορία, η οποία έχει έναν διακόπτη που καθορίζει ποια κλάση θα δημιουργηθεί με βάση την είσοδο.
Αυτό λειτουργεί καλά κατ 'αρχήν, αλλά εάν έχετε πολλές διαφορετικές πιθανές εισόδους (πολλά στοιχεία σε ένα enum ή ίσως η είσοδος είναι ένας συνδυασμός πολλών διαφορετικών τιμών), μπορεί να γίνει κουραστικό και επιρρεπές σε σφάλματα να διατηρηθεί και ο σχεδιασμός έχει πάντα το μειονέκτημα ότι θα χρειαστεί να τροποποιήσετε την εν λόγω μέθοδο κατασκευής εάν προσθέσετε ποτέ μια νέα υποκλάση ή κάνετε αλλαγές σε ποια υποκλάση πρέπει να χρησιμοποιηθεί με βάση ποια είσοδο.
Ευτυχώς, υπάρχει ένας πολύ πιο κομψός, αλλά δυστυχώς και πολύ λιγότερο γνωστός, τρόπος για να γίνει αυτό, δηλαδή με τη χρήση του πλαισίου SysExtension.
Αυτό το πλαίσιο εκμεταλλεύεται τα χαρακτηριστικά που μπορείτε να χρησιμοποιήσετε για να διακοσμήσετε τις υποκλάσεις σας για να κάνετε το σύστημα ικανό να καταλάβει ποια υποκλάση πρέπει να χρησιμοποιηθεί για το χειρισμό τι. Θα χρειαστείτε ακόμα μια μέθοδο κατασκευής, αλλά αν γίνει σωστά, δεν θα χρειαστεί ποτέ να την τροποποιήσετε κατά την προσθήκη νέων υποκλάσεων.
Ας δούμε ένα φανταστικό παράδειγμα και ας πούμε ότι πρόκειται να εφαρμόσετε μια ιεραρχία που κάνει κάποιο είδος επεξεργασίας με βάση τον πίνακα InventTrans. Η επεξεργασία που πρέπει να γίνει εξαρτάται από το StatusReceipt και το StatusIssue των καρτελών, καθώς και από το αν οι εγγραφές σχετίζονται με το SalesLine, το PurchLine ή κανένα από τα δύο. Ήδη τώρα, εξετάζετε πολλούς διαφορετικούς συνδυασμούς.
Ας πούμε λοιπόν ότι γνωρίζετε ότι προς το παρόν χρειάζεται να χειριστείτε μόνο μια χούφτα συνδυασμών, αλλά γνωρίζετε επίσης ότι θα σας ζητηθεί να είστε σε θέση να χειριστείτε όλο και περισσότερους συνδυασμούς με την πάροδο του χρόνου.
Ας το κρατήσουμε σχετικά απλό και ας πούμε ότι προς το παρόν χρειάζεται μόνο να χειριστείτε εγγραφές που σχετίζονται με το SalesLine με ένα StatusIssue του ReservPhysical ή του ReservOrdered, όλοι οι άλλοι συνδυασμοί μπορούν να αγνοηθούν προς το παρόν, αλλά επειδή γνωρίζετε ότι θα πρέπει να τους χειριστείτε αργότερα, θα θελήσετε να σχεδιάσετε τον κώδικά σας με τρόπο που να τον καθιστά εύκολα επεκτάσιμο.
Η ιεραρχία σας μπορεί να μοιάζει κάπως έτσι προς το παρόν:
- Ο επεξεργαστής μου
- MyProcessor_Sales
- MyProcessor_Sales_ReservOrdered
- MyProcessor_Sales_ReservPhysical
- MyProcessor_Sales
Τώρα, θα μπορούσατε εύκολα να εφαρμόσετε μια μέθοδο στην υπερκλάση που δημιουργεί μια υποκλάση βασισμένη σε ένα ModuleInventPurchSales και ένα enum StatusIssue. Αλλά στη συνέχεια θα πρέπει να τροποποιείτε την υπερκλάση κάθε φορά που προσθέτετε μια υποκλάση, και αυτή δεν είναι πραγματικά η ιδέα της κληρονομικότητας στον αντικειμενοστραφή προγραμματισμό. Σε τελική ανάλυση, δεν χρειάζεται να τροποποιείτε το 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
{
}
Μπορείτε φυσικά να ονομάσετε τις τάξεις σας με όποιον τρόπο θέλετε, το σημαντικό μέρος εδώ είναι ότι διακοσμείτε τις τάξεις σας με χαρακτηριστικά που αντιστοιχούν στο είδος της επεξεργασίας που κάνουν. (Ωστόσο, λάβετε υπόψη ότι υπάρχουν συμβάσεις ονομασίας για ιεραρχίες κλάσεων στο Dynamics AX και είναι πάντα καλή ιδέα να τις ακολουθείτε, αν είναι δυνατόν).
Τώρα που έχετε διακοσμήσει τις σας για να προσδιορίσετε τι είδους επεξεργασία κάνει καθεμία από αυτές, μπορείτε να επωφεληθείτε από το πλαίσιο SysExtension για να δημιουργήσετε αντικείμενα των υποκλάσεων, όπως απαιτείται.
Στην υπερκλάση σας (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;
}
Το πραγματικά ενδιαφέρον μέρος - και πραγματικά το αντικείμενο (συγχωρέστε το λογοπαίγνιο) ολόκληρης αυτής της ανάρτησης - είναι η μέθοδος getClassFromSysAttribute() στην κλάση SysExtensionAppClassFactory. Αυτό που κάνει αυτή η μέθοδος είναι ότι αποδέχεται το όνομα της υπερκλάσης μιας ιεραρχίας (και αυτή η υπερκλάση δεν χρειάζεται να βρίσκεται στην κορυφή της ιεραρχίας· σημαίνει απλώς ότι μόνο που επεκτείνουν αυτήν την κλάση θα είναι επιλέξιμες) και ένα αντικείμενο χαρακτηριστικού.
Στη συνέχεια, επιστρέφει ένα αντικείμενο μιας κλάσης που επεκτείνει την καθορισμένη υπερκλάση και διακοσμείται με ένα αντίστοιχο χαρακτηριστικό.
Μπορείτε προφανώς να προσθέσετε όσο περισσότερη επικύρωση ή λογική θέλετε στη μέθοδο κατασκευής, αλλά το σημαντικό συμπέρασμα εδώ είναι ότι μόλις εφαρμοστεί, δεν θα χρειαστεί ποτέ να τροποποιήσετε ξανά αυτήν τη μέθοδο. Μπορείτε να προσθέσετε υποκλάσεις στην ιεραρχία και εφόσον φροντίσετε να τις διακοσμήσετε κατάλληλα, η μέθοδος κατασκευής θα τις βρει ακόμα κι αν δεν υπήρχαν όταν γράφτηκε.
Τι γίνεται με την απόδοση; Ειλικρινά δεν έχω προσπαθήσει να το συγκρίνω, αλλά η αίσθηση του εντέρου μου είναι ότι αυτό πιθανότατα αποδίδει χειρότερα από τον κλασικό σχεδιασμό δήλωσης διακόπτη. Ωστόσο, λαμβάνοντας υπόψη ότι μακράν τα περισσότερα ζητήματα επιδόσεων στο Dynamics AX προκαλούνται από την πρόσβαση στη βάση δεδομένων, δεν θα ανησυχούσα πάρα πολύ για αυτό.
Φυσικά, εάν εφαρμόζετε κάτι που θα απαιτήσει χιλιάδες αντικείμενα να δημιουργηθούν γρήγορα, ίσως θελήσετε να διερευνήσετε περαιτέρω, αλλά στις κλασικές περιπτώσεις όπου απλώς δημιουργείτε ένα μόνο αντικείμενο για να κάνετε κάποια μακρά επεξεργασία, αμφιβάλλω ότι θα έχει σημασία. Επίσης, λαμβάνοντας υπόψη τη συμβουλή αντιμετώπισης προβλημάτων (επόμενη παράγραφος), φαίνεται ότι το πλαίσιο SysExtension βασίζεται στην προσωρινή αποθήκευση, οπότε σε ένα τρέχον σύστημα αμφιβάλλω ότι έχει σημαντικό χτύπημα απόδοσης. Αντιμετώπιση προβλημάτων: Εάν η μέθοδος κατασκευής δεν εντοπίσει τις υποκλάσεις σας, παρόλο που είστε βέβαιοι ότι είναι σωστά διακοσμημένες, μπορεί να είναι πρόβλημα προσωρινής αποθήκευσης. Δοκιμάστε να διαγράψετε τις κρυφές μνήμες τόσο στον υπολογιστή-πελάτη όσο και στο διακομιστή. Δεν θα πρέπει να είναι απαραίτητο να επανεκκινήσετε πραγματικά το AOS, αλλά μπορεί να είναι η έσχατη λύση.