Miklix

Korišćenje okvira SisEktension da biste saznali koju podklasu treba instancirati u Dinamics AKS KSNUMKS

Objavio: 19. mart 2025. 21:25:41 UTC

Ovaj članak opisuje kako koristiti malo poznati okvir SisEktension u Dinamics AKS 2012 i Dinamics 365 for Operations za instanciranje podklasa na osnovu ukrasa atributa, omogućavajući lako proširiv dizajn hijerarhije klase obrade.


Ova stranica je mašinski prevedena sa engleskog jezika kako bi bila dostupna što većem broju ljudi. Nažalost, mašinsko prevođenje još uvek nije usavršena tehnologija, tako da može doći do grešaka. Ako želite, možete pogledati originalnu englesku verziju ovde:

Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012

Informacije u ovom postu su zasnovane na Dinamics AKS 2012 R3. Može ili ne mora da važi za druge verzije. (Ažuriranje: Mogu da potvrdim da informacije u ovom članku važe i za Dinamics KSNUMKS for Operations)

Kada implementirate klase obrade u Dinamics AKS-u, često se suočavate sa kreiranjem hijerarhije klasa u kojoj svaka podklasa odgovara vrednosti enuma ili ima neku drugu vezu podataka. Klasičan dizajn je da se u super klasi napravi metoda, koja ima prekidač koji određuje koja klasa će instancirati na osnovu ulaza.

Ovo dobro funkcioniše u principu, ali ako imate mnogo različitih mogućih ulaza (mnogi elementi u enumu ili možda ulaz je kombinacija nekoliko različitih vrednosti), može postati dosadan i sklon greškama za održavanje i dizajn uvek ima nedostatak da ćete morati da modifikujete pomenuti metod konstrukcije ako ikada dodate novu podklasu ili napravite izmene u kojoj podklasi treba da se koristi na osnovu kog ulaza.

Srećom, postoji mnogo elegantniji, ali nažalost i mnogo manje poznat, način da se to uradi, naime upotrebom SisEktension okvira.

Ovaj okvir koristi atribute koje možete koristiti za ukrašavanje vaših podklasa kako bi sistem mogao da shvati koja podklasa treba da se koristi za rukovanje šta. I dalje će vam biti potreban metod konstrukcije, ali ako se to uradi ispravno, nikada nećete morati da ga menjate prilikom dodavanja novih podklasa.

Pogledajmo imaginarni primer i recimo da ćete implementirati hijerarhiju koja radi neku vrstu obrade zasnovane na InventTrans tabeli. Koja obrada zavisi od StatusReceipt i StatusIssue zapisa, kao i od toga da li se zapisi odnose na SalesLine, PurchLine ili nijedno. Već sada, gledate mnogo različitih kombinacija.

Recimo onda da znate da za sada trebate samo da se nosite sa pregršt kombinacija, ali takođe znate da će se od vas tražiti da budete u stanju da se nosite sa sve više i više kombinacija tokom vremena.

Hajde da bude relativno jednostavno i recimo da za sada treba samo da rukujete zapisima koji se odnose na SalesLine sa StatusIssue of ReservPhysical ili ReservOrdered, sve ostale kombinacije mogu biti ignorisane za sada, ali pošto znate da ćete morati da ih rešite kasnije, želećete da dizajnirate svoj kod na način koji ga čini lako proširivim.

Vaša hijerarhija za sada može izgledati ovako:

  • Pretraga
    • MyProcessor_Sales
      • MyProcessor_Sales_ReservOrdered
      • MyProcessor_Sales_ReservPhysical

Sada možete lako implementirati metod u super klasi koji instancira podklasu zasnovanu na ModuleInventPurchSales i StatusIssue enum. Ali tada ćete morati da modifikujete super klasu svaki put kada dodate podklasu, a to zapravo nije ideja nasleđivanja u objektno orijentisanom programiranju. Na kraju krajeva, ne morate da modifikujete RunBaseBatch ili SisOperationServiceBase svaki put kada dodate novi batch posao.

Umesto toga, možete koristiti SisEktension okvir. To će zahtevati da dodate još jednu klasu, koja treba da proširi SisAttribute. Ova klasa će se koristiti kao atribut sa kojim možete ukrasiti svoje časove obrade.

Ova klasa je veoma slična načinu na koji biste napravili klasu ugovora o podacima za implementaciju SisOperation-a, u tome što će imati neke članove podataka i parm metode za dobijanje i postavljanje tih vrednosti.

U našem slučaju, ClassDeclaration može izgledati ovako:

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

Potrebno je da napravite novi () metod za instanciranje svih članova podataka. Ako želite možete dati neke ili sve od njih podrazumevane vrednosti, ali ja to nisam uradio.

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

    super();

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

I takođe bi trebalo da implementirate parm metod za svakog člana podataka, ali ja sam ih ovde izostavio jer sam siguran da znate kako se to radi - u suprotnom, hajde da to smatramo vežbom ;-)

Sada možete da koristite svoju klasu atributa da ukrasite svaku od vaših klasa obrade. Na primer, deklaracije klase mogu izgledati ovako:

[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
{
}

Naravno, možete imenovati svoje klase kako god želite, važan deo ovde je da ukrasite svoje klase atributima koji odgovaraju vrsti obrade koju rade. (Ali imajte na umu da postoje konvencije imenovanja za hijerarhije klasa u Dinamics AKS-u i uvek je dobra ideja da ih pratite, ako je moguće).

Sada kada ste ukrasili svoje klase da biste identifikovali kakvu obradu svaki od njih radi, možete iskoristiti SisEktension okvir za instanciranje objekata podklasa po potrebi.

U svojoj super klasi (MiProcessor), možete dodati metodu konstrukcije ovako:

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;
}

Zaista interesantan deo - i zaista objekat (oprostite na igri reči) celog ovog posta - je metoda getClassFromSysAttribute() u klasi SysExtensionAppClassFactori. Ono što ovaj metod radi jeste da prihvata ime super klase hijerarhije (a ova super klasa ne mora da bude na vrhu hijerarhije; to jednostavno znači da će samo klase koje proširuju ovu klasu biti podobne) i atributni objekat.

Zatim vraća objekat klase koji proširuje navedenu super klasu i ukrašen je odgovarajućim atributom.

Očigledno možete dodati onoliko daljnje validacije ili logike metodi konstrukcije koliko želite, ali važno je da jednom implementirate, nikada više ne biste trebali da modifikujete ovaj metod. Možete dodati podklase u hijerarhiju i sve dok se pobrinete da ih ukrasite na odgovarajući način, metoda konstrukcije će ih pronaći iako nisu postojale kada su napisane.

Šta je sa performansama? Iskreno nisam pokušao da ga uporedim, ali moj osećaj je da je ovo verovatno lošije od klasičnog dizajna prekidača. Međutim, s obzirom na to da je daleko većina problema sa performansama u Dinamics AKS-u uzrokovana pristupom bazi podataka, ne bih se previše brinuo o tome.

Naravno, ako implementirate nešto što će zahtevati hiljade objekata da se brzo kreiraju, možda ćete želeti da istražite dalje, ali u klasičnim slučajevima kada samo instancirate jedan objekat da biste uradili neku dugotrajnu obradu, sumnjam da će to biti važno. Takođe, s obzirom na moj savet za rešavanje problema (sledeći paragraf), čini se da se SisEktension okvir oslanja na keširanje, tako da u pokrenutom sistemu sumnjam da ima značajan pogodak performansi.

Rešavanje problema: Ako metoda konstrukcije ne pronađe vaše podklase iako ste sigurni da su pravilno uređene, to može biti problem keširanja. Pokušajte da obrišete keš memoriju i na klijentu i na serveru. Ne bi trebalo da bude neophodno da se zapravo ponovo pokrene AOS, ali to može biti poslednje sredstvo.

Podeli na BlueskiPodeli na FejsbukuPodeli na LinkedInPodeli na TumblrPodeli na XPodeli na LinkedInPin na Pinterest

Mikkel Christensen

O autoru

Mikkel Christensen
Mikel je tvorac i vlasnik miklix.com. Ima preko 20 godina iskustva kao profesionalni kompjuterski programer / programer i trenutno je zaposlen sa punim radnim vremenom za veliku evropsku IT korporaciju. Kada ne bloguje, on provodi svoje slobodno vreme na širokom spektru interesovanja, hobija i aktivnosti, što se u određenoj meri može odraziti na različite teme koje se obrađuju na ovoj veb stranici.