Miklix

Gebruik die SysExtension-raamwerk om uit te vind watter subklas in Dynamics AX 2012 geïnstalleer moet word

Gepubliseer: 16 Februarie 2025 om 00:26:31 UTC

Hierdie artikel beskryf hoe u die min bekende SysExtension-raamwerk in Dynamics AX 2012 en Dynamics 365 for Operations kan gebruik om subklasse te instansieer op grond van kenmerkversierings, wat 'n maklik uitbreidbare ontwerp van 'n verwerkingsklashiërargie moontlik maak.


Hierdie bladsy is masjienvertaal uit Engels om dit vir soveel mense moontlik toeganklik te maak. Ongelukkig is masjienvertaling nog nie 'n volmaakte tegnologie nie, dus kan foute voorkom. As jy verkies, kan jy die oorspronklike Engelse weergawe hier sien:

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

Die inligting in hierdie pos is gebaseer op Dynamics AX 2012 R3. Dit mag al dan nie geldig wees vir ander weergawes nie. (Opdatering: ek kan bevestig dat die inligting in hierdie artikel ook geldig is vir Dynamics 365 for Operations)

Wanneer u verwerkingsklasse in Dynamics AX implementeer, word u dikwels gekonfronteer met die skep van 'n klashiërargie waarin elke subklas ooreenstem met 'n opsommingswaarde of 'n ander datakoppeling het. 'n Klassieke ontwerp is om dan 'n konstruksiemetode in die superklas te hê, wat 'n skakelaar het wat bepaal watter klas om te instansieer op grond van die invoer.

Dit werk in beginsel goed, maar as u baie verskillende moontlike insette het (baie elemente in 'n opsomming of miskien is die invoer 'n kombinasie van verskillende waardes), kan dit vervelig en foutgevoelig raak om te onderhou en die ontwerp het altyd die nadeel dat u die konstruksiemetode moet verander as u ooit 'n nuwe subklas byvoeg of veranderinge aanbring aan watter subklas gebruik moet word op grond van watter invoer.

Gelukkig is daar 'n baie eleganter, maar ongelukkig ook baie minder bekende, manier om dit te doen, naamlik deur gebruik te maak van die SysExtension-raamwerk.

Hierdie raamwerk maak gebruik van eienskappe wat jy kan gebruik om jou subklasse te versier om die stelsel in staat te stel om uit te vind watter subklas gebruik moet word om wat te hanteer. Jy sal steeds 'n konstruksiemetode nodig hê, maar as dit korrek gedoen word, hoef jy dit nooit te verander wanneer jy nuwe subklasse byvoeg nie.

Kom ons kyk na 'n denkbeeldige voorbeeld en sê dat jy 'n hiërargie gaan implementeer wat 'n soort verwerking doen gebaseer op die InventTrans-tabel. Watter verwerking gedoen moet word, hang af van die StatusReceipt en StatusIssue van die rekords, asook of die rekords verband hou met SalesLine, PurchLine of nie een van die twee nie. Reeds nou kyk jy na baie verskillende kombinasies.

Kom ons sê dan dat jy weet dat jy vir eers net 'n handjievol van die kombinasies hoef te hanteer, maar jy weet ook dat jy gevra sal word om mettertyd meer en meer kombinasies te kan hanteer.

Kom ons hou dit relatief eenvoudig en sê dat jy vir eers net rekords wat verband hou met SalesLine hoef te hanteer met 'n StatusIssue van ReservPhysical of ReservOrdered, alle ander kombinasies kan vir eers geïgnoreer word, maar aangesien jy weet jy sal dit later moet hanteer, sal jy jou kode wil ontwerp op 'n manier wat dit maklik uitbreidbaar maak.

Jou hiërargie kan vir eers so lyk:

  • MyVerwerker
    • MyProcessor_Sales
      • MyProcessor_Sales_ReservOrdered
      • MyProcessor_Sales_ReservPhysical

Nou kan u maklik 'n metode in die superklas implementeer wat 'n subklas instansieer op grond van 'n ModuleInventPurchSales en 'n StatusIssue-opsomming. Maar jy sal dan die superklas moet verander elke keer as jy 'n subklas byvoeg, en dit is nie regtig die idee van oorerwing in objekgeoriënteerde programmering nie. U hoef immers nie RunBaseBatch of SysOperationServiceBase te verander elke keer as u 'n nuwe bondeltaak byvoeg nie.

In plaas daarvan kan jy van die SysExtension-raamwerk gebruik maak. Dit sal vereis dat jy nog 'n klas byvoeg, wat SysAttribute moet uitbrei. Hierdie klas sal gebruik word as die kenmerk waarmee jy jou verwerkingsklasse kan versier.

Hierdie klas is baie soortgelyk aan hoe u 'n datakontrakklas vir 'n SysOperation-implementering sou maak, deurdat dit 'n paar datalede en parm-metodes sal hê om die waardes te kry en in te stel.

In ons geval kan die ClassDeclaration so lyk:

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

U moet 'n nuwe () metode maak om alle datalede te instansieer. As u wil, kan u sommige of almal standaardwaardes gee, maar ek het dit nie gedoen nie.

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

    super();

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

En u moet ook 'n parm-metode vir elke datalid implementeer, maar ek het dit hier weggelaat, want ek is seker dat u weet hoe om dit te doen - andersins, laat ons dit as 'n oefening beskou ;-)

Nou kan jy jou kenmerkklas gebruik om elkeen van jou verwerkingsklasse te versier. Die klasverklarings kan byvoorbeeld soos volg lyk:

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

Jy kan natuurlik jou klasse noem soos jy wil, die belangrike deel hier is dat jy jou klasse versier met eienskappe wat ooreenstem met watter soort verwerking hulle doen. indien moontlik).

Noudat jy jou klasse versier het om te identifiseer watter soort verwerking elkeen van hulle doen, kan jy voordeel trek uit die SysExtension-raamwerk om voorwerpe van die subklasse te instansieer soos nodig.

In u superklas (MyProcessor) kan u 'n konstruksiemetode soos volg byvoeg:

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

Die werklik interessante deel - en regtig die voorwerp (verskoon die woordspeling) van hierdie hele pos - is die getClassFromSysAttribute () -metode in die SysExtensionAppClassFactory-klas. Wat hierdie metode doen, is dat dit die naam van die superklas van 'n hiërargie aanvaar (en hierdie superklas hoef nie bo-aan die hiërargie te wees nie; dit beteken eenvoudig dat slegs klasse wat hierdie klas uitbrei, in aanmerking kom) en 'n kenmerkvoorwerp.

Dit gee dan 'n voorwerp van 'n klas terug wat die gespesifiseerde superklas uitbrei en versier is met 'n ooreenstemmende kenmerk.

Jy kan natuurlik soveel verdere validering of logika by die konstrukmetode voeg as wat jy wil, maar die belangrike wegneemete hier is dat sodra dit geïmplementeer is, jy nooit weer hierdie metode hoef te verander nie. Jy kan subklasse by die hiërargie voeg en solank jy seker maak dat jy dit toepaslik versier, sal die konstruksiemetode dit vind, al het hulle nie bestaan toe dit geskryf is nie.

Wat van prestasie? Ek het eerlikwaar nie probeer om dit te meet nie, maar my gevoel is dat dit waarskynlik slegter presteer as die klassieke skakelaarverklaringontwerp. As in ag geneem word dat verreweg die meeste prestasiekwessies in Dynamics AX deur databasistoegang veroorsaak word, sal ek my egter nie te veel daaroor bekommer nie.

Natuurlik, as jy iets implementeer wat sal vereis dat duisende voorwerpe vinnig geskep moet word, wil jy dalk verder ondersoek, maar in die klassieke gevalle waar jy net 'n enkele voorwerp instansieer om 'n lang verwerking te doen, twyfel ek of dit saak sal maak. Met inagneming van my probleemoplossingswenk (volgende paragraaf), blyk dit ook dat die SysExtension-raamwerk staatmaak op caching, so in 'n lopende stelsel twyfel ek of dit 'n beduidende prestasietreffer het. Probleemoplossing: As die konstruksiemetode nie jou subklasse vind nie, alhoewel jy seker is dat hulle korrek versier is, kan dit 'n kasprobleem wees. Probeer om kas op beide kliënt en bediener skoon te maak. Dit behoort nie nodig te wees om die AOS werklik te herbegin nie, maar dit kan laaste uitweg wees.

Deel op BlueskyDeel op FacebookDeel op LinkedInDeel op TumblrDeel op XDeel op LinkedInSpeld op Pinterest

Mikkel Bang Christensen

Oor die skrywer

Mikkel Bang Christensen
Mikkel is die skepper en eienaar van miklix.com. Hy het meer as 20 jaar ondervinding as 'n professionele rekenaarprogrammeerder/sagteware-ontwikkelaar en is tans voltyds in diens van 'n groot Europese IT-korporasie. Wanneer hy nie blog nie, spandeer hy sy vrye tyd aan 'n groot verskeidenheid belangstellings, stokperdjies en aktiwiteite, wat tot 'n mate weerspieël kan word in die verskeidenheid onderwerpe wat op hierdie webwerf gedek word.