2010-03-16

CacheMetadata(…), alltid vår kompis

När vi bygger våra egna kodaktiviteter (NativeActivity, CodeActivity, AsyncActivity) i WF4.0 skall vi alltid göra en override på CacheMetadata och bidra med vår kunskap om den aktivitet som vi skapat.
Dokumentationen på MSDN ger oss följande exempel

protected override void CacheMetadata(NativeActivityMetadata metadata)
{
//call base.CacheMetadata to add the Activities and Variables to this activity's metadata
base.CacheMetadata(metadata);
//add the private implementation variable: currentIndex
metadata.AddImplementationVariable(this.currentIndex);
}



vilket tyvärr är ett lysande exempel på ett dåligt sätt att implementera den metoden. För att förstå varför det är dåligt måste vi gå på djupet.


Vad gör CacheMetadata? Jo, den funktionen ger oss möjlighet att


  • Skapa avancerade valideringsregler (validering är något vi alltid skall skapa)

  • Registrera child activities

  • Deklarera variabler

  • Tala om att aktiviteten vi skapat kräver en viss extension

  • Registrera en egen extension provider



Varför duger då inte exemplet ovan? För att svara på det så måste vi kika på vad base.CacheMetadata gör.


  • Hanterar alla publika properties av typen Activity

  • Hanterar alla publika properties av typen Variable

  • Hanterar alla publika properties av typen InArgument


Allt detta gör den via reflektion vilket naturligtvis kostar oss i prestanda. För att förbättra prestanda bör vi alltså göra detta manuellt och inte anropa base.CacheMetadata. Vi måste hur som helst alltid göra en override för att hantera scenarion som inte täcks av de tre som hanteras av runtimen.

Om vi tittar på hur alla inbyggda aktiviteter gör så föregår de med gott exempel och gör en override, det är bara MSDN som visar på något annat.

Många saker i aktivitetsmodellen för WF4 är bättre och enklare än föregångaren men detta är ett exempel på när vi bör dyka ned i detaljerna för att leverera en bra lösning.

2 kommentarer:

Patrik Hollender sa...

Hej. Det står att man kan kontakta dig direkt. Men hur gör man det?

Daniel sa...

Maila mig på daniel.karlsson(a)connecta.se

(a) är alltså @, skriver så för att undvika onödigt spam :)