Miklix

Dynamics AX 2012 SysOperation Framework Hurtigt overblik

Udgivet: 15. februar 2025 kl. 22.33.04 UTC
Sidst opdateret: 12. januar 2026 kl. 08.38.46 UTC

Denne artikel giver et hurtigt overblik (eller et trick sheet) over, hvordan man implementerer behandlingsklasser og batchjob i SysOperation-frameworket i Dynamics AX 2012 og Dynamics 365 for Operations.


Denne side er blevet maskinoversat fra engelsk for at gøre den tilgængelig for så mange mennesker som muligt. Desværre er maskinoversættelse endnu ikke en perfekt teknologi, så der kan forekomme fejl. Hvis du foretrækker det, kan du se den originale engelske version her:

Dynamics AX 2012 SysOperation Framework Quick Overview

Oplysningerne i dette indlæg er baseret på Dynamics AX 2012 R3. De er muligvis ikke gyldige for andre versioner. (Opdatering: Jeg kan bekræfte, at oplysningerne i denne artikel også er gyldige for Dynamics 365 for Operations)


Dette indlæg er blot ment som et hurtigt overblik og en cheatsheet. Hvis du er ny inden for SysOperation-frameworket, anbefaler jeg kraftigt, at du også læser Microsofts whitepaper om emnet. Oplysningerne her kan være nyttige, hvis du bare har brug for et hurtigt indblik i de forskellige klasser, der er involveret i udvikling af operationer med dette framework.

Der er variationer, men når jeg bruger frameworket, implementerer jeg typisk tre klasser:

  • Datakontrakt (bør udvide SysOperationDataContractBase)
  • Tjeneste (bør udvide SysOperationServiceBase)
  • Controller (skal udvide SysOperationServiceController)

Derudover kan jeg også implementere en UIBuilder-klasse (skal udvide SysOperationUIBuilder), men det er kun nødvendigt, hvis dialogen af en eller anden grund skal være mere avanceret end det, som frameworket genererer automatisk.


Datakontrakt

Datakontrakten indeholder de datamedlemmer, der er nødvendige for din operation. Den kan sammenlignes med den typiske CurrentList-makro, der er defineret i RunBase-frameworket, men implementeres i stedet som en klasse. Datakontrakten bør udvide SysOperationDataContractBase, men vil fungere, selvom den ikke gør det. Fordelen ved at udvide superklassen er, at den giver nogle sessionsoplysninger, der kan være nyttige.

[DataContractAttribute]
class MyDataContract extends SysOperationDataContractBase
{
    ItemId itemId;
}

I dette eksempel er itemId et datamedlem. Du skal implementere en parm-metode for hvert datamedlem og tagge det med DataMemberAttribute, så frameworket ved, hvad det er. Dette gør det muligt for frameworket automatisk at opbygge dialogen for dig.

[DataMemberAttribute]
public ItemId parmItemId(ItemId _itemId = itemId)
{
    ;

    itemId = _itemId;
    return itemId;
}


Service

Serviceklassen er den klasse, der indeholder den faktiske forretningslogik. Den beskæftiger sig ikke med at vise dialoger, batchbehandling eller lignende – det er controllerklassens ansvar. Ved at adskille dette er det mere sandsynligt, at du designer din kode godt og laver mere genbrugelig kode.

Ligesom datakontraktklassen behøver serviceklassen ikke at arve fra noget bestemt, men den bør arve fra SysOperationServiceBase-klassen, i det mindste hvis du forventer, at servicen vil blive kørt som et batchjob, da superklassen giver nogle oplysninger om batchkonteksten. Metoden, der starter operationen (dvs. kører forretningslogikken), skal tage et objekt fra din datakontraktklasse som input og bør dekoreres med [SysEntryPointAttribute]. For eksempel:

class MyService extends SysOperationServiceBase
{
}

Med en metode kaldet run:

[SysEntryPointAttribute]
public void run(MyDataContract _dataContract)
{
    // run business logic here
}


Controller

Controller-klassen håndterer udførelsen og batchbehandlingen af din operation. Den sørger også for, at koden udføres i CIL for maksimal ydeevne. Controller-klassen arver typisk fra SysOperationServiceController-klassen, selvom der også findes andre muligheder.

class MyController extends SysOperationServiceController
{
}

Superklassens konstruktør tager et klassenavn, et metodenavn og (valgfrit) en udførelsestilstand som parametre. Klasse- og metodenavnene skal være navnet på din serviceklasse og den metode, der skal køres på den. Så du kan implementere din controllers konstruktionsmetode sådan her:

public static MyController construct()
{
    ;

    return new MyController(classStr(MyService),
    methodStr(MyService, run));
}

Så kan hovedmetoden i MyController-klassen være så simpel som

public static void main(Args _args)
{
    ;

    MyController::construct().startOperation();
}

Og du er stort set færdig. Ovenstående er naturligvis et meget simpelt eksempel, og frameworket indeholder et væld af andre muligheder, men dette fungerer som et hurtigt overblik, hvis du har brug for en opfriskning, når du ikke har brugt frameworket i et stykke tid.

Yderligere læsning

Hvis du kunne lide dette indlæg, kan du måske også lide disse forslag:


Del på BlueskyDel på FacebookDel på LinkedInDel på TumblrDel på XDel på LinkedInFastgør på Pinterest

Mikkel Christensen

Om forfatteren

Mikkel Christensen
Mikkel er skaberen og ejeren af miklix.com. Han har over 20 års erfaring som professionel computerprogrammør/softwareudvikler og er i øjeblikket fuldtidsansat i en stor europæisk IT-virksomhed. Når han ikke blogger, bruger han sin fritid på en lang række interesser, hobbyer og aktiviteter, som i et vist omfang afspejles i de mange forskellige emner, der dækkes på dette websted.