SysExtension Frameworkin käyttäminen Dynamics AX 2012:ssa luotavan alaluokan selvittämiseen
Julkaistu: 16. helmikuuta 2025 klo 0.25.40 UTC
Viimeksi päivitetty: 12. tammikuuta 2026 klo 8.42.58 UTC
Tässä artikkelissa kuvataan, miten Dynamics AX 2012:n ja Dynamics 365 for Operationsin vähän tunnettua SysExtension-kehystä käytetään attribuuttikoristeluihin perustuvien alakategorioiden luomiseen, mikä mahdollistaa käsittelyluokkahierarkian helposti laajennettavan suunnittelun.
Using the SysExtension Framework to Find Out Which Subclass to Instantiate in Dynamics AX 2012
Tämän viestin tiedot perustuvat Dynamics AX 2012 R3:een. Ne eivät välttämättä päde muihin versioihin. (Päivitys: Voin vahvistaa, että tämän artikkelin tiedot pätevät myös Dynamics 365 for Operationsille.)
Kun toteutat prosessointiluokkia Dynamics AX:ssä, kohtaat usein luokkahierarkian luomisen, jossa jokainen aliluokka vastaa luetteloarvoa tai sillä on jokin muu datakytkentä. Klassinen suunnittelutapa on sitten sisällyttää construct-metodi superluokkaan, jossa on kytkin, joka määrittää, mikä luokka luodaan syötteen perusteella.
Tämä toimii periaatteessa hyvin, mutta jos sinulla on useita erilaisia mahdollisia syötteitä (useita elementtejä enumissa tai ehkä syöte on useiden eri arvojen yhdistelmä), sen ylläpito voi olla työlästä ja virhealtista. Suunnittelulla on aina se haittapuoli, että joudut muokkaamaan kyseistä rakennusmenetelmää, jos koskaan lisäät uuden alaluokan tai teet muutoksia siihen, mitä alaluokkaa tulisi käyttää minkäkin syötteen perusteella.
Onneksi on olemassa paljon tyylikkäämpi, mutta valitettavasti myös paljon vähemmän tunnettu tapa tehdä tämä, nimittäin SysExtension-kehyksen avulla.
Tämä viitekehys hyödyntää attribuutteja, joita voit käyttää alakategorioidesi koristeluun, jotta järjestelmä pystyy selvittämään, mitä alaluokkaa tulisi käyttää minkäkin käsittelyyn. Tarvitset silti konstruktiomenetelmän, mutta jos se tehdään oikein, sinun ei koskaan tarvitse muokata sitä uusia alakategorioita lisätessäsi.
Tarkastellaan kuvitteellista esimerkkiä, jossa aiot toteuttaa hierarkian, joka suorittaa jonkinlaista käsittelyä InventTrans-taulukon perusteella. Suoritettava käsittely riippuu tietueiden StatusReceipt- ja StatusIssue-arvoista sekä siitä, liittyvätkö tietueet SalesLine-, PurchLine- vai kumpaankaan. Jo nyt tarkastellaan monia erilaisia yhdistelmiä.
Oletetaan sitten, että tiedät, että tällä hetkellä sinun tarvitsee käsitellä vain kourallista yhdistelmiä, mutta tiedät myös, että sinulta pyydetään kykyä käsitellä yhä useampia yhdistelmiä ajan myötä.
Pidetään se suhteellisen yksinkertaisena ja sanotaan, että nyt sinun tarvitsee käsitellä vain SalesLine-tietueita, joiden StatusIssue-arvo on ReservPhysical tai ReservOrdered. Kaikki muut yhdistelmät voidaan jättää huomiotta toistaiseksi, mutta koska tiedät, että sinun on käsiteltävä niitä myöhemmin, sinun kannattaa suunnitella koodisi siten, että sitä on helppo laajentaa.
Hierarkiasi saattaa näyttää tällä hetkellä suunnilleen tältä:
- OmaProsessoriOmaProsessori_MyyntiOmaProsessori_Myynti_VarausTilattuOmaProsessori_Myynti_VarausFyysinen
Nyt voisit helposti toteuttaa superluokassa metodin, joka luo aliluokan instanssin ModuleInventPurchSales- ja StatusIssue-enum-arvojen perusteella. Mutta silloin sinun on muokattava superluokkaa joka kerta, kun lisäät aliluokan, eikä se oikeastaan ole periytymisen idea olio-ohjelmoinnissa. Loppujen lopuksi sinun ei tarvitse muokata RunBaseBatch- tai SysOperationServiceBase-metodia joka kerta, kun lisäät uuden eräajon.
Sen sijaan voit käyttää SysExtension-kehystä. Se edellyttää toisen luokan lisäämistä, jonka on laajennettava SysAttribute-luokkaa. Tätä luokkaa käytetään attribuuttina, jolla voit koristella prosessointiluokkiasi.
Tämä luokka on hyvin samankaltainen kuin SysOperation-toteutuksen datasopimusluokan tekeminen siinä mielessä, että siinä on joitakin datajäseniä ja parm-metodeja näiden arvojen hakemiseen ja asettamiseen.
Meidän tapauksessamme luokkailmoitus voi näyttää suunnilleen tältä:
{
ModuleInventPurchSales module;
StatusIssue statusIssue;
StatusReceipt statusReceipt
}
Sinun täytyy luoda new()-metodi kaikkien dataelementtien instanssien luomiseksi. Voit halutessasi antaa joillekin tai kaikille elementeille oletusarvot, mutta en ole tehnyt niin.
StatusIssue _statusIssue,
StatusReceipt _statusReceipt)
{
;
super();
module = _module;
statusIssue = _statusIssue;
statusReceipt = _statusReceipt;
}
Ja sinun tulisi myös toteuttaa parm-metodi jokaiselle dataelementille, mutta olen jättänyt ne pois tästä, koska olen varma, että tiedät miten se tehdään - muuten pidetään sitä harjoituksena ;-)
Nyt voit käyttää attribuuttiluokkaasi koristellaksesi kutakin käsittelyluokkaasi. Esimerkiksi luokkamäärittelyt voisivat näyttää tältä:
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
{
}
Voit tietenkin nimetä luokkiasi haluamallasi tavalla. Tärkeintä on, että lisäät luokkiisi määritteet, jotka vastaavat niiden suorittamaa prosessointia. (Muista kuitenkin, että Dynamics AX:ssä on luokkahierarkioille nimeämiskäytäntöjä, ja niitä on aina hyvä noudattaa, jos mahdollista.)
Nyt kun olet määrittänyt luokkiesi suoritustyypin ja määrittänyt, millaista prosessointia kukin luo, voit hyödyntää SysExtension-kehystä luodaksesi tarvittaessa avaluokkien objektien instansseja.
Superluokkaasi (MyProcessor) voisit lisätä seuraavanlaisen konstruktiomenetelmän:
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;
}
Todella mielenkiintoinen osa – ja oikeastaan koko tämän viestin objekti (anteeksi sanaleikki) – on SysExtensionAppClassFactory-luokan getClassFromSysAttribute()-metodi. Tämä metodi hyväksyy hierarkian superluokan nimen (eikä tämän superluokan tarvitse olla hierarkian huipulla; se tarkoittaa yksinkertaisesti sitä, että vain tätä luokkaa laajentavat luokat ovat kelvollisia) ja attribuuttiobjektin.
Sitten se palauttaa luokan objektin, joka laajentaa määritettyä superluokkaa ja on koristeltu vastaavalla attribuutilla.
Voit tietenkin lisätä construct-metodiin niin paljon validointia tai logiikkaa kuin haluat, mutta tärkein asia on, että kun metodi on kerran otettu käyttöön, sitä ei enää koskaan tarvitse muokata. Voit lisätä hierarkiaan alakategorioita, ja kunhan varmistat niiden asianmukaisen koristelun, construct-metodi löytää ne, vaikka niitä ei olisi ollut olemassa metodin kirjoitushetkellä.
Entä suorituskyky? En rehellisesti sanottuna ole yrittänyt vertailla sitä, mutta mutu-tuntemukseni on, että tämä toimii luultavasti huonommin kuin klassinen switch-lausesuunnittelu. Ottaen kuitenkin huomioon, että ylivoimaisesti suurin osa Dynamics AX:n suorituskykyongelmista johtuu tietokannan käytöstä, en olisi siitä liikaa huolissani.
Tietenkin, jos toteutat jotain, joka vaatii tuhansien objektien nopeaa luomista, kannattaa ehkä tutkia asiaa tarkemmin, mutta klassisissa tapauksissa, joissa vain luodaan yksi objekti pitkien käsittelyjen suorittamiseksi, epäilen, onko sillä merkitystä. Lisäksi, ottaen huomioon vianmääritysvihjeeni (seuraava kappale), näyttää siltä, että SysExtension-kehys perustuu välimuistiin, joten käynnissä olevassa järjestelmässä epäilen, että sillä olisi merkittävää suorituskyvyn heikkenemistä.
Vianmääritys: Jos construct-metodi ei löydä aliluokkiasi, vaikka olet varma, että ne on järjestetty oikein, kyseessä voi olla välimuistiongelma. Kokeile tyhjentää välimuistit sekä asiakasohjelmassa että palvelimella. AOS:n uudelleenkäynnistyksen ei pitäisi olla tarpeen, mutta se voi olla viimeinen keino.
Lisälukemista
Jos pidit tästä postauksesta, saatat pitää myös näistä ehdotuksista:
- Merkkijonojen muotoilu makrolla ja strFmt:llä Dynamics AX 2012:ssa
- Muunna real merkkijonoksi kaikilla desimaaliluvuilla Dynamics AX 2012:ssa
- Poista oikeushenkilö (yritystilit) Dynamics AX 2012:ssa
