Miklix

Χρήση του πλαισίου 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

Τώρα, θα μπορούσατε εύκολα να εφαρμόσετε μια μέθοδο στην υπερκλάση που δημιουργεί μια υποκλάση βασισμένη σε ένα ModuleInventPurchSales και ένα enum StatusIssue. Αλλά στη συνέχεια θα πρέπει να τροποποιείτε την υπερκλάση κάθε φορά που προσθέτετε μια υποκλάση, και αυτή δεν είναι πραγματικά η ιδέα της κληρονομικότητας στον αντικειμενοστραφή προγραμματισμό. Σε τελική ανάλυση, δεν χρειάζεται να τροποποιείτε το RunBaseBatch ή το SysOperationServiceBase κάθε φορά που προσθέτετε μια νέα εργασία δέσμης.

Αντίθετα, μπορείτε να χρησιμοποιήσετε το πλαίσιο SysExtension. Αυτό θα απαιτήσει να προσθέσετε μια άλλη κλάση, η οποία πρέπει να επεκτείνει το SysAttribute. Αυτή η κλάση θα χρησιμοποιηθεί ως χαρακτηριστικό με το οποίο μπορείτε να διακοσμήσετε τις τάξεις επεξεργασίας σας.

Αυτή η κλάση είναι πολύ παρόμοια με το πώς θα κάνατε μια κλάση συμβολαίου δεδομένων για μια υλοποίηση SysOperation, καθώς θα έχει ορισμένα μέλη δεδομένων και μεθόδους parm για τη λήψη και τον ορισμό αυτών των τιμών.

Στην περίπτωσή μας, το ClassDeclaration μπορεί να μοιάζει κάπως έτσι:

class MyProcessorSystemAttribute extends SysAttribute
{
    ModuleInventPurchSales  module;
    StatusIssue             statusIssue;
    StatusReceipt           statusReceipt
}

Πρέπει να δημιουργήσετε μια νέα μέθοδο () για τη δημιουργία όλων των μελών δεδομένων. Αν θέλετε, μπορείτε να δώσετε μερικές ή όλες τις προεπιλεγμένες τιμές, αλλά δεν το έχω κάνει αυτό.

public void new(ModuleInventPurchSales  _module,
                StatusIssue             _statusIssue,
                StatusReceipt           _statusReceipt)
{
    ;

    super();

    module          = _module;
    statusIssue     = _statusIssue;
    statusReceipt   = _statusReceipt;
}

Και θα πρέπει επίσης να εφαρμόσετε μια μέθοδο parm για κάθε μέλος δεδομένων, αλλά έχω παραλείψει αυτά εδώ, καθώς είμαι βέβαιος ότι ξέρετε πώς να το κάνετε αυτό - διαφορετικά, ας το θεωρήσουμε μια άσκηση ;-)

Τώρα μπορείτε να χρησιμοποιήσετε την κλάση χαρακτηριστικών σας για να διακοσμήσετε κάθε μία από τις επεξεργασίας σας. Για παράδειγμα, οι δηλώσεις κλάσης θα μπορούσαν να έχουν την εξής μορφή:

[MyProcessorSystemAttribute(ModuleInventPurchSales::Sales,
                            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), θα μπορούσατε να προσθέσετε μια μέθοδο κατασκευής όπως αυτή:

public static MyProcessor construct(ModuleInventPurchSales _module,
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, αλλά μπορεί να είναι η έσχατη λύση.

Μοιραστείτε το στο BlueskyΚοινή χρήση στο FacebookΚοινοποίηση στο LinkedInΜοιραστείτε το στο TumblrΚοινοποίηση στο XΚοινοποίηση στο LinkedInΚαρφιτσώστε στο Pinterest

Μίκελ Μπανγκ Κρίστενσεν

Σχετικά με τον συγγραφέα

Μίκελ Μπανγκ Κρίστενσεν
Ο Μιχαήλ είναι ο δημιουργός και ιδιοκτήτης του miklix.com. Έχει πάνω από 20 χρόνια εμπειρίας ως επαγγελματίας προγραμματιστής υπολογιστών/προγραμματιστής λογισμικού και σήμερα εργάζεται με πλήρη απασχόληση σε μια μεγάλη ευρωπαϊκή εταιρεία πληροφορικής. Όταν δεν ασχολείται με το ιστολόγιο, αφιερώνει τον ελεύθερο χρόνο του σε ένα ευρύ φάσμα ενδιαφερόντων, χόμπι και δραστηριοτήτων, τα οποία μπορεί σε κάποιο βαθμό να αντικατοπτρίζονται στην ποικιλία των θεμάτων που καλύπτονται σε αυτόν τον ιστότοπο.