08/11/2012
For enhver udvikler, der arbejder med Microsoft Dynamics 365, er en dyb forståelse af platformens event execution pipeline ikke bare en fordel – det er en nødvendighed. At vide, hvornår og hvordan din kode eksekverer i forhold til kerneoperationen, er afgørende for at bygge robuste, effektive og skalerbare løsninger. Uden denne viden risikerer man at skabe kode, der er ineffektiv, forårsager uventede fejl eller i værste fald skaber uendelige løkker, der kan påvirke hele systemets ydeevne. Denne artikel vil guide dig igennem de forskellige faser i plugin-eksekveringen, med særligt fokus på de tre faser, du kan tilpasse: Pre-Validation, Pre-Operation og Post-Operation. Vi vil afdække deres forskelle, ideelle anvendelsesscenarier og de faldgruber, du skal undgå.

Hvad er Plugin Execution Pipeline?
Plugin Execution Pipeline er en sekventiel proces, som Dynamics 365 følger, når en kerneoperation (som at oprette, opdatere eller slette en post) udføres. Denne pipeline er opdelt i flere faser, hvilket giver udviklere mulighed for at indsætte brugerdefineret logik på specifikke tidspunkter i processen. Ved at registrere et plugin på en bestemt fase kan du validere data, ændre data, før de gemmes, eller udføre opfølgende handlinger, efter data er gemt.
Der er overordnet fire hovedfaser, som er relevante for en udvikler:
- Fase 10: Pre-Validation - Kører uden for databasetransaktionen.
- Fase 20: Pre-Operation - Kører inden i databasetransaktionen, men før kerneoperationen.
- Main Operation - Systemets kerneoperation (f.eks. SQL Create/Update). Denne fase kan ikke tilpasses.
- Fase 40: Post-Operation - Kører inden i databasetransaktionen, men efter kerneoperationen er afsluttet.
Valget af den korrekte fase er afgørende for din løsnings funktionalitet og ydeevne.
En Dybdegående Gennemgang af Faserne
Lad os nu dykke ned i hver af de brugerdefinerbare faser for at forstå deres unikke karakteristika og anvendelsesmuligheder.

Pre-Validation (Fase 10)
Pre-Validation er den første fase i pipelinen. Det mest afgørende kendetegn ved denne fase er, at den eksekverer uden for databasetransaktionen. Det betyder, at hvis dit plugin fejler eller kaster en undtagelse (exception) i denne fase, vil hele operationen blive annulleret, men der vil ikke ske et 'rollback' af en databasetransaktion, da den endnu ikke er startet. Dette gør det til det ideelle sted at udføre valideringslogik.
- Uden for transaktionen: Perfekt til at annullere en operation med en brugerdefineret fejlmeddelelse uden den performance-omkostning, som et transaktions-rollback medfører.
- Før sikkerhedstjek: Vær opmærksom på, at koden i denne fase kører, før platformen har verificeret, om den kaldende bruger har de nødvendige rettigheder til at udføre operationen.
- Anvendelsesscenarie: Forestil dig, at en bruger forsøger at oprette en ny kontakt. I Pre-Validation-fasen kan du tjekke, om en kontakt med samme e-mailadresse allerede eksisterer. Hvis den gør, kan du kaste en
InvalidPluginExecutionExceptionmed en klar besked til brugeren. Operationen stopper her, hurtigt og effektivt.
Pre-Operation (Fase 20)
Når vi når Pre-Operation-fasen, er vi trådt inden i databasetransaktionen. Alt, hvad der sker fra dette punkt og frem, er en del af en samlet transaktion. Hvis en fejl opstår her eller i en senere fase, vil hele transaktionen blive rullet tilbage for at sikre dataintegritet. Denne fase kører lige før, at systemets hovedoperation gemmer data i databasen.
- Inden i transaktionen: Giver datasikkerhed. Hvis noget fejler, efterlades systemet i sin oprindelige tilstand.
- Før hovedoperationen: Dette er det mest effektive sted at ændre værdier på den post (entity), der bliver behandlet. Du kan direkte modificere 'Target' parameteren i input-konteksten, og dine ændringer vil blive inkluderet i den efterfølgende databaseoperation uden behov for et ekstra servicekald.
- Vigtig advarsel: Undgå at annullere operationer i denne fase, medmindre det er absolut nødvendigt. At kaste en undtagelse her vil tvinge et fuldt rollback af databasetransaktionen, hvilket er en ressourcekrævende proces, der kan påvirke systemets ydeevne negativt.
- Anvendelsesscenarie: En sælger opdaterer en ordrelinje, hvilket ændrer den samlede pris. I Pre-Operation-fasen på ordren kan du beregne den nye samlede ordresum og opdatere feltet 'totalamount' direkte på ordre-entiteten. Dette sikrer, at den korrekte total gemmes i én enkelt operation.
Post-Operation (Fase 40)
Post-Operation er den sidste brugerdefinerbare fase, og den kører også inden i databasetransaktionen, men efter at hovedoperationen er fuldført. På dette tidspunkt er dataene blevet gemt i databasen. Hvis du opretter en ny post, vil dens unikke ID (GUID) nu være tilgængeligt i output-parametrene.

- Efter hovedoperationen: Dataene er bekræftet og gemt. Du kan nu sikkert udføre handlinger, der er afhængige af, at denne operation lykkedes.
- Ideel til relaterede handlinger: Denne fase er perfekt til at arbejde med relaterede poster. For eksempel, efter en ordre er oprettet (og har fået et ID), kan du i Post-Operation-fasen oprette relaterede opfølgningsopgaver.
- Den store faldgrube: Den mest almindelige fejl er at opdatere den samme post, som udløste plugin'et, i Post-Operation-fasen. Hvis dit plugin er registreret på 'Update'-meddelelsen for en ordre, og du i Post-Operation-fasen kalder
service.Update(order)igen, vil du udløse 'Update'-meddelelsen på ny. Dette skaber en uendelig løkke, som kan låse systemet.
Sammenligningstabel: Pre-Validation vs. Pre-Operation vs. Post-Operation
| Funktion | Pre-Validation (Fase 10) | Pre-Operation (Fase 20) | Post-Operation (Fase 40) |
|---|---|---|---|
| Database Transaktion | Udenfor | Indeni | Indeni |
| Timing ift. kerneoperation | Langt før | Lige før | Lige efter |
| Ideel til at annullere | Ja (Høj ydeevne) | Nej (Lav ydeevne) | Nej (Lav ydeevne) |
| Ideel til at ændre 'Target' data | Nej | Ja (Mest effektivt) | Nej (Kræver ekstra servicekald) |
| Adgang til Record ID (ved 'Create') | Nej | Nej | Ja |
| Primært formål | Validering og tidlig annullering. | Modificering af data før lagring. | Udføre handlinger på relaterede poster. |
Praktiske Eksempler og Bedste Praksis
For at cementere forståelsen er her et par scenarier, der illustrerer bedste praksis:
Scenarie: Oprettelse af et nyt Salgsemne
- Pre-Validation: Tjek om salgsemnets telefonnummer har et gyldigt format. Hvis ikke, annuller operationen med en fejlmeddelelse.
- Pre-Operation: Standardiser landekoden på telefonnummeret (f.eks. tilføj +45, hvis det mangler) og konverter emnenavnet til stort forbogstav. Disse ændringer sker direkte på 'Target' entiteten.
- Post-Operation: Når salgsemnet er oprettet og har et ID, send en notifikation til den tildelte sælger via en e-mail eller opret en opgave.
Scenarie: Opdatering af en Sag (Case) til 'Løst'
- Pre-Validation: Kontroller om alle tilknyttede opgaver til sagen er markeret som fuldførte. Hvis ikke, forhindr sagen i at blive løst ved at kaste en undtagelse.
- Pre-Operation: Sæt 'Løsningsdato' (Actual End) feltet til dags dato og tid. Dette gøres direkte på sags-entiteten.
- Post-Operation: Send en bekræftelses-e-mail til kunden, der oprindeligt oprettede sagen, med information om at deres sag nu er løst.
Ofte Stillede Spørgsmål (FAQ)
Kan jeg annullere en operation i Pre-Operation-fasen?
Ja, teknisk set kan du kaste en InvalidPluginExecutionException for at stoppe processen. Det er dog stærkt frarådet. Fordi fasen er inde i en databasetransaktion, vil annulleringen udløse et fuldt 'rollback', hvilket er en tung operation, der har en betydelig negativ indvirkning på systemets ydeevne. Brug altid Pre-Validation til forventede valideringsfejl og annulleringer.
Hvorfor er det en dårlig idé at opdatere den samme post i en Post-Operation plugin?
Hvis dit plugin er registreret på 'Update'-meddelelsen, vil et kald til service.Update() på den samme post i Post-Operation-fasen få 'Update'-hændelsen til at fyre igen. Dette får dit plugin til at køre sig selv igen og igen, hvilket skaber en uendelig løkke. Dette kan forbruge serverressourcer hurtigt og i sidste ende føre til systemfejl.
Hvad er forskellen på context.InputParameters["Target"] og et Pre-Entity Image?
I en 'Update'-operation indeholder context.InputParameters["Target"] kun de felter, der bliver ændret. Hvis du har brug for at se værdien af et felt, *før* ændringen fandt sted (men som ikke selv bliver ændret), skal du registrere et 'Pre-Entity Image'. Dette image giver dig et snapshot af posten, som den så ud i databasen, før opdateringen startede.

Hvornår skal jeg vælge Pre-Operation frem for Post-Operation?
Tommelfingerreglen er: Hvis din logik har brug for at ændre værdier på den post, der behandles, skal du bruge Pre-Operation. Det er langt mere effektivt, da det kun kræver én databaseoperation. Hvis din logik skal udføre en separat handling (som at oprette en relateret post eller sende en e-mail) baseret på det vellykkede resultat af den første operation, skal du bruge Post-Operation.
At mestre Dynamics 365s event execution pipeline er en af de vigtigste færdigheder for en platformudvikler. Ved bevidst at vælge den korrekte fase for din brugerdefinerede logik kan du skrive kode, der ikke kun er funktionel, men også yderst effektiv og vedligeholdelsesvenlig. Husk de grundlæggende principper: Valider i Pre-Validation, modificer i Pre-Operation, og ager på resultatet i Post-Operation. Denne strukturerede tilgang vil sikre, at dine løsninger er robuste og skalerbare i mange år fremover.
Hvis du vil læse andre artikler, der ligner Dynamics 365: Dybdegående Guide til Plugin-faser, kan du besøge kategorien Teknologi.
