Miklix

Duke përdorur kornizën SysExtension për të gjetur se cila nënklasë do të instantiate në Dynamics AX 2012

Publikuar: 16 shkurt 2025 në 12:26:29 e paradites, UTC
Përditësimi i fundit: 12 janar 2026 në 8:43:37 e paradites, UTC

Ky artikull përshkruan se si të përdoret kuadri pak i njohur SysExtension në Dynamics AX 2012 dhe Dynamics 365 for Operations për të krijuar instanca të nënklasave bazuar në dekorimet e atributeve, duke lejuar një dizajn lehtësisht të zgjerueshëm të një hierarkie të klasës së përpunimit.


Kjo faqe u përkthye me makinë nga anglishtja për ta bërë të aksesueshme për sa më shumë njerëz. Fatkeqësisht, përkthimi me makinë nuk është ende një teknologji e përsosur, kështu që mund të ndodhin gabime. Nëse preferoni, mund ta shikoni versionin origjinal në anglisht këtu:

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

Informacioni në këtë postim bazohet në Dynamics AX 2012 R3. Mund të jetë ose jo i vlefshëm për versione të tjera. (Përditësim: Mund të konfirmoj që informacioni në këtë artikull është i vlefshëm edhe për Dynamics 365 for Operations)

Kur zbatoni klasa përpunimi në Dynamics AX, shpesh përballeni me krijimin e një hierarkie klasash në të cilën secila nënklasë korrespondon me një vlerë enumërimi ose ka ndonjë lidhje tjetër të të dhënave. Një dizajn klasik është të kesh më pas një metodë ndërtimi në superklasën, e cila ka një çelës që përcakton se cila klasë duhet të krijohet në bazë të të dhënave hyrëse.

Kjo funksionon mirë në parim, por nëse keni shumë të dhëna të ndryshme të mundshme (shumë elementë në një numërim ose ndoshta të dhënat e dhëna është një kombinim i disa vlerave të ndryshme), mirëmbajtja e saj mund të bëhet e lodhshme dhe e prirur ndaj gabimeve, dhe dizajni gjithmonë ka disavantazhin që do t'ju duhet të modifikoni metodën e ndërtimit nëse shtoni ndonjëherë një nënklasë të re ose bëni ndryshime në atë se cila nënklasë duhet të përdoret bazuar në cilën të dhënë të dhëna.

Për fat të mirë, ekziston një mënyrë shumë më elegante, por për fat të keq edhe shumë më pak e njohur, për ta bërë këtë, përkatësisht duke përdorur kornizën SysExtension.

Ky kuadër shfrytëzon atributet që mund të përdorni për të dekoruar nënklasat tuaja në mënyrë që sistemi të jetë në gjendje të përcaktojë se cila nënklasë duhet të përdoret për të trajtuar çfarë. Do t'ju duhet ende një metodë konstruksioni, por nëse bëhet siç duhet, nuk do të keni nevojë ta modifikoni kurrë atë kur shtoni nënklasa të reja.

Le të shohim një shembull imagjinar dhe të themi se do të zbatoni një hierarki që bën një lloj përpunimi bazuar në tabelën InventTrans. Se cili përpunim duhet të bëhet varet nga StatusReceipt dhe StatusIssue të të dhënave, si dhe nëse të dhënat lidhen me SalesLine, PurchLine apo asnjërën. Tashmë, po shikoni shumë kombinime të ndryshme.

Le të themi atëherë se e dini që për momentin duhet të trajtoni vetëm një numër të vogël kombinimesh, por gjithashtu e dini se me kalimin e kohës do t'ju kërkohet të jeni në gjendje të trajtoni gjithnjë e më shumë kombinime.

Le ta mbajmë relativisht të thjeshtë dhe të themi se për momentin duhet të trajtoni vetëm të dhënat që lidhen me SalesLine me një StatusIssue të ReservPhysical ose ReservOrdered, të gjitha kombinimet e tjera mund të injorohen për momentin, por meqenëse e dini që do t'ju duhet t'i trajtoni ato më vonë, do të duhet ta dizajnoni kodin tuaj në një mënyrë që ta bëjë atë lehtësisht të zgjerueshëm.

Hierarkia juaj mund të duket diçka e tillë për momentin:

  • ProcesoriMyProcessor_MySalesProcesoriMySales_RezervaIPorositurProcesoriMySales_RezervaFizike

Tani, mund të implementoni lehtësisht një metodë në superklasën që krijon një instancë të një nënklase bazuar në një ModuleInventPurchSales dhe një numërim StatusIssue. Por më pas do t'ju duhet të modifikoni superklasën sa herë që shtoni një nënklasë, dhe kjo nuk është realisht ideja e trashëgimisë në programimin e orientuar nga objektet. Në fund të fundit, nuk keni nevojë të modifikoni RunBatch ose SysOperationServiceBase sa herë që shtoni një punë të re batch.

Në vend të kësaj, mund të përdorni strukturën SysExtension. Kjo do t'ju kërkojë të shtoni një klasë tjetër, e cila duhet të zgjerojë SysAttribute. Kjo klasë do të përdoret si atributi me të cilin mund të dekoroni klasat tuaja të përpunimit.

Kjo klasë është shumë e ngjashme me mënyrën se si do të krijonit një klasë kontrate të dhënash për një implementim të SysOperation, në atë që do të ketë disa anëtarë të të dhënave dhe metoda parm për të marrë dhe vendosur ato vlera.

Në rastin tonë, ClassDeclaration mund të duket diçka e tillë:

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

Duhet të krijoni një metodë new() për të krijuar instanca të të gjithë anëtarëve të të dhënave. Nëse dëshironi, mund t'u jepni disave ose të gjithëve vlera fillestare, por unë nuk e kam bërë këtë.

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

    super();

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

Dhe duhet të implementoni gjithashtu një metodë parm për secilin anëtar të të dhënave, por i kam lënë jashtë ato këtu pasi jam i sigurt që dini si ta bëni këtë - përndryshe, le ta konsiderojmë si një ushtrim ;-)

Tani mund ta përdorni klasën tuaj të atributeve për të dekoruar secilën prej klasave tuaja të përpunimit. Për shembull, deklaratat e klasës mund të duken kështu:

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

Sigurisht, mund t’i emërtoni klasat tuaja si të dëshironi, pjesa e rëndësishme këtu është që t’i dekoroni klasat tuaja me atribute që korrespondojnë me llojin e përpunimit që ato bëjnë. (Por mbani mend se ekzistojnë konventa emërtimi për hierarkitë e klasave në Dynamics AX dhe është gjithmonë një ide e mirë t’i ndiqni ato, nëse është e mundur).

Tani që i keni dekoruar klasat tuaja për të identifikuar se çfarë lloj përpunimi bën secila prej tyre, mund të përfitoni nga kuadri SysExtension për të krijuar raste të objekteve të nënklasave sipas nevojës.

Në superklasën tuaj (MyProcessor), mund të shtoni një metodë ndërtimi si kjo:

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

Pjesa vërtet interesante - dhe në të vërtetë objekti (më falni për lojën e fjalëve) i të gjithë këtij postimi - është metoda getClassFromSysAttribute() në klasën SysExtensionAppClassFactory. Ajo që bën kjo metodë është se pranon emrin e superklasës së një hierarkie (dhe kjo superklasë nuk ka nevojë të jetë në krye të hierarkisë; thjesht do të thotë se vetëm klasat që zgjerojnë këtë klasë do të jenë të pranueshme) dhe një objekt atributi.

Pastaj kthen një objekt të një klase që zgjeron superklasën e specifikuar dhe është i dekoruar me një atribut përkatës.

Sigurisht, mund t’i shtoni metodës së ndërtimit sa më shumë validim ose logjikë të mëtejshme që dëshironi, por mësimi i rëndësishëm këtu është se pasi të zbatohet, nuk duhet ta modifikoni më kurrë këtë metodë. Mund të shtoni nënklasa në hierarki dhe për sa kohë që siguroheni që t’i dekoroni ato siç duhet, metoda e ndërtimit do t’i gjejë ato edhe pse nuk ekzistonin kur u shkrua.

Po në lidhje me performancën? Sinqerisht nuk jam përpjekur ta krahasoj, por kam përshtypjen se kjo ndoshta performon më keq se dizajni klasik i deklaratës së ndërrimit. Megjithatë, duke marrë parasysh se deri më tani shumica e problemeve të performancës në Dynamics AX shkaktohen nga qasja në bazën e të dhënave, nuk do të shqetësohesha shumë për këtë.

Sigurisht, nëse po implementoni diçka që do të kërkojë krijimin e shpejtë të mijëra objekteve, mund të dëshironi të hetoni më tej, por në rastet klasike ku thjesht krijoni një objekt të vetëm për të bërë një përpunim të gjatë, dyshoj se do të ketë rëndësi. Gjithashtu, duke marrë parasysh këshillën time për zgjidhjen e problemeve (paragrafi tjetër), duket se kuadri SysExtension mbështetet në ruajtjen në memorje, kështu që në një sistem që funksionon dyshoj se ka një rënie të ndjeshme të performancës.

Zgjidhja e problemeve: Nëse metoda e ndërtimit nuk i gjen nënklasat tuaja edhe pse jeni të sigurt se ato janë dekoruar saktë, mund të jetë një problem me ruajtjen në memorje. Provoni të pastroni memorjet në memorje si në klient ashtu edhe në server. Nuk duhet të jetë e nevojshme të rinisni AOS-in, por mund të jetë zgjidhja e fundit.

Lexime të mëtejshme

Nëse ju pëlqeu ky postim, mund t'ju pëlqejnë edhe këto sugjerime:


Shpërndaje në BlueskyShpërndaje në FacebookNdani në LinkedInShpërndaje në TumblrShpërndaje në XNdani në LinkedInPin në Pinterest

Mikkel Christensen

Rreth Autorit

Mikkel Christensen
Mikkel është krijuesi dhe pronari i miklix.com. Ai ka mbi 20 vjet përvojë si programues profesional kompjuteri/zhvillues softuerësh dhe aktualisht është i punësuar me kohë të plotë për një korporatë të madhe evropiane IT. Kur nuk bën blog, ai e kalon kohën e lirë në një gamë të gjerë interesash, hobish dhe aktivitetesh, të cilat mund të reflektohen në një farë mase në shumëllojshmërinë e temave të mbuluara në këtë faqe interneti.