Miklix

SysExtension ჩარჩოს გამოყენებით იმის გასარკვევად, თუ რომელი ქვეკლასი უნდა იყოს მყისიერი Dynamics AX 2012-ში

გამოქვეყნებულია: 16 თებერვალი, 2025, 00:28:48 UTC
ბოლო განახლება: 12 იანვარი, 2026, 08:43:45 UTC

ეს სტატია აღწერს, თუ როგორ გამოვიყენოთ Dynamics AX 2012-სა და Dynamics 365 for Operations-ში ნაკლებად ცნობილი SysExtension ჩარჩო ატრიბუტების დეკორაციების საფუძველზე ქვეკლასების ინსტანცირებისთვის, რაც დამუშავების კლასის იერარქიის ადვილად გაფართოების საშუალებას იძლევა.


ეს გვერდი მანქანურად ითარგმნა ინგლისურიდან, რათა რაც შეიძლება მეტი ადამიანისთვის ხელმისაწვდომი ყოფილიყო. სამწუხაროდ, მანქანური თარგმანი ჯერ კიდევ არ არის სრულყოფილი ტექნოლოგია, ამიტომ შეიძლება მოხდეს შეცდომები. თუ გსურთ, შეგიძლიათ ნახოთ ორიგინალური ინგლისური ვერსია აქ:

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-ში დამუშავების კლასების იმპლემენტაციისას, ხშირად აწყდებით კლასის იერარქიის შექმნას, რომელშიც თითოეული ქვეკლასი შეესაბამება ჩამოთვლის მნიშვნელობას ან აქვს სხვა მონაცემთა შეერთება. კლასიკური დიზაინია სუპერ კლასში კონსტრუქტის მეთოდის ქონა, რომელსაც აქვს გადამრთველი, რომელიც განსაზღვრავს, თუ რომელი კლასი უნდა შეიქმნას შეყვანის მონაცემების მიხედვით.

ეს პრინციპში კარგად მუშაობს, მაგრამ თუ თქვენ გაქვთ მრავალი განსხვავებული შესაძლო შეყვანა (ჩამოთვლაში მრავალი ელემენტი ან შესაძლოა შეყვანა იყოს რამდენიმე განსხვავებული მნიშვნელობის კომბინაცია), მისი შენარჩუნება შეიძლება გახდეს დამღლელი და შეცდომებისადმი მიდრეკილი, ხოლო დიზაინს ყოველთვის აქვს ის ნაკლი, რომ თქვენ დაგჭირდებათ აღნიშნული კონსტრუქციის მეთოდის მოდიფიცირება, თუ ოდესმე დაამატებთ ახალ ქვეკლასს ან შეიტანთ ცვლილებებს იმაში, თუ რომელი ქვეკლასი უნდა იქნას გამოყენებული, რომელი შეყვანის მიხედვით.

საბედნიეროდ, ამის გაკეთების გაცილებით ელეგანტური, მაგრამ სამწუხაროდ, ასევე გაცილებით ნაკლებად ცნობილი გზა არსებობს, კერძოდ, SysExtension ჩარჩოს გამოყენებით.

ეს ჩარჩო იყენებს ატრიბუტებს, რომელთა გამოყენებაც შეგიძლიათ თქვენი ქვეკლასების გასაფორმებლად, რათა სისტემამ შეძლოს გაარკვიოს, რომელი ქვეკლასი რის დასამუშავებლად უნდა იქნას გამოყენებული. თქვენ მაინც დაგჭირდებათ კონსტრუქტის მეთოდი, მაგრამ თუ სწორად გაკეთდა, ახალი ქვეკლასების დამატებისას მისი შეცვლა არასდროს დაგჭირდებათ.

მოდით განვიხილოთ წარმოსახვითი მაგალითი და ვთქვათ, რომ თქვენ აპირებთ იერარქიის იმპლემენტაციას, რომელიც InventTrans ცხრილის საფუძველზე ახორციელებს რაიმე სახის დამუშავებას. შესასრულებელი დამუშავება დამოკიდებულია ჩანაწერების StatusReceipt-სა და StatusIssue-ზე, ასევე იმაზე, დაკავშირებულია თუ არა ჩანაწერები SalesLine-თან, PurchLine-თან თუ არცერთთან. უკვე, თქვენ უყურებთ მრავალ სხვადასხვა კომბინაციას.

ვთქვათ, რომ თქვენ იცით, რომ ამ ეტაპზე მხოლოდ რამდენიმე კომბინაციის დამუშავება გჭირდებათ, მაგრამ ასევე იცით, რომ დროთა განმავლობაში მოგეთხოვებათ უფრო და უფრო მეტი კომბინაციის დამუშავება.

მოდით, შედარებით მარტივად შევარჩიოთ და ვთქვათ, რომ ამ ეტაპზე მხოლოდ SalesLine-თან დაკავშირებული ჩანაწერების დამუშავებაა საჭირო, რომელთა StatusIssue-ია ReservPhysical ან ReservOrdered. ყველა სხვა კომბინაციის იგნორირება ამჟამად შესაძლებელია, მაგრამ რადგან იცით, რომ მოგვიანებით მათი დამუშავება მოგიწევთ, კოდი ისე უნდა შექმნათ, რომ ის ადვილად გაფართოებადი იყოს.

თქვენი იერარქია შესაძლოა ახლა ასე გამოიყურებოდეს:

  • MyProcessorMyProcessor_SalesMyProcessor_Sales_ReservშეკვეთილიMyProcessor_Sales_Reservფიზიკური

ახლა, თქვენ შეგიძლიათ მარტივად განახორციელოთ მეთოდი სუპერ კლასში, რომელიც ქმნის ქვეკლასს ModuleInventPurchSales-ისა და StatusIssue-ის ნუმერაციის საფუძველზე. თუმცა, შემდეგ თქვენ დაგჭირდებათ სუპერ კლასის შეცვლა ყოველ ჯერზე, როდესაც დაამატებთ ქვეკლასს და ეს სინამდვილეში არ არის მემკვიდრეობის იდეა ობიექტზე ორიენტირებულ პროგრამირებაში. ბოლოს და ბოლოს, თქვენ არ გჭირდებათ RunBatch-ის ან SysOperationServiceBase-ის შეცვლა ყოველ ჯერზე, როდესაც დაამატებთ ახალ პაკეტურ დავალებას.

ამის ნაცვლად, შეგიძლიათ გამოიყენოთ SysExtension ჩარჩო. ამისათვის დაგჭირდებათ კიდევ ერთი კლასის დამატება, რომელსაც SysAttribute-ის გაფართოება დასჭირდება. ეს კლასი გამოყენებული იქნება როგორც ატრიბუტი, რომლითაც შეგიძლიათ თქვენი დამუშავების კლასების გაფორმება.

ეს კლასი ძალიან ჰგავს SysOperation იმპლემენტაციისთვის მონაცემთა კონტრაქტის კლასის შექმნის მეთოდს, რადგან მას ექნება რამდენიმე მონაცემთა წევრი და parm მეთოდი ამ მნიშვნელობების მისაღებად და დასაყენებლად.

ჩვენს შემთხვევაში, ClassDeclaration შეიძლება ასე გამოიყურებოდეს:

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

ყველა მონაცემთა წევრის ინსტანცირებისთვის საჭიროა new() მეთოდის შექმნა. თუ გსურთ, შეგიძლიათ ზოგიერთ ან ყველა მათგანს მიანიჭოთ ნაგულისხმევი მნიშვნელობები, მაგრამ მე ეს არ გამიკეთებია.

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 წელზე მეტი გამოცდილება, როგორც პროფესიონალი კომპიუტერული პროგრამისტი/პროგრამული უზრუნველყოფის შემქმნელი და ამჟამად მუშაობს სრულ განაკვეთზე დიდ ევროპულ IT კორპორაციაში. როდესაც ბლოგს არ წერს, თავისუფალ დროს ატარებს ინტერესების, ჰობიებისა და აქტივობების უზარმაზარ სპექტრზე, რაც შეიძლება გარკვეულწილად აისახოს ამ ვებსაიტზე გაშუქებულ თემებზე.