MIX Essentials

by DotNetNerd 22. May 2008 20:49

Arrangementet 

Onsdag inden jeg fik set Manchester United blive kronet som europas konger, var jeg til MIX Essentials i Cinemaxx i København. Vi tog afsted 4 mand høj, eller to mandlige udviklere og to kvindlige grafikere for at være helt præcis, for at lære lidt mere om Silverlight, og søge inspiration til hvordan vi kan benytte det i vores virksomhed. Uden at jeg gik derfra med hænderne over hovedet, synes jeg det var et udemærket arrangement. Niveauet var måske lidt lavere end forventet og der var knap så mange rigtige eksempler som vi kunne have ønsket os, men vi fik da set nogle bud på hvad Silverlight kan bruges til. Mere vigtigt for mig ihvertfald var at vi fik nogle links og navnene på nogle tools sådan at jeg har noget mere at gå videre med.

Links til inspiration

En af de ting jeg ikke selv havde hørt så meget til var deepzoom og dertil værktøjet deepzoom composer, der er i beta og kan hentes direkte hos Microsoft. Deepzoom giver som navnet antydet mulighed for at man kan lave virkelig store billeder i virkelig høj kvalitet, som downloades delvist til klienten sådan at der kun sendes de detaljer der er nødvendige i forhold til det gældende zoom niveau. Et fedt eksempel på dette og hvad det kan bruges til kan ses på hardrockcafe.com under memorabelia.

Af tools der blev fremvist synes jeg især KAXAML ser lækkert ud. Det er et lille letvægts værktøj til at arbejde med XAML i et splitview. Helt sikkert et tool jeg selv skal lege lidt med fremover :) Et andet tool der så spændende ud er Silverlight Spy der er til at udforske hvordan Silverlight applikationer er skrevet. Og som med alle andre teknologier er der naturligvis også en WPF Profiler, som nok skal vise sig uundværlig på et tidspunkt, som den slags tools ofte viser sig at gøre.

Sidst i den mere futuristiske afdeling så og hørte vi lidt mere til surface som mange umiddelbart forbinder med "a big ass table". Naturligvis er perspektivet i teknologien meget mere og andet end den prototype som det her bord er - men som så tit før ser den almindelige forbruger ikke længere end på det der er lige foran dem. Jeg tror imidlertid nok teknologien skal vinde frem, og håber da også selv en dag at komme til at lave en surface baseret løsning.

Tags: ,

Test driven development – my two cents.

by DotNetNerd 11. May 2008 13:07

Test driven development – my two cents.

Unit testing er en metode til at teste at en individuel enhed kildekode fungerer korrekt.  Egentlig har unit testing været brugt i flere årtier, men begrebet har den seneste tid udviklet sig til lige at være et buzzword der er oppe i tiden – især som metodik i form af Test Driven Development. TDD bliver der blogget enormt meget om for tiden – og netop derfor vil jeg ikke kaste mig ud i at forklare hvad det er, men lader det være en forudsætning for at læse videre.

Udbredelsen af TDD/unit testing er en stor del af grundlaget for at Microsoft har kastet sig over at lave MVC frameworket, som et alternativ til den klassiske måde at udvikle ASP.NET applikationer på.

Rob Conery der står bag SubSonic, og nu er ansat hos Microsoft er for tiden i gang med en serie på sin blog som han kalder MVC storefront, hvor han går efter at blive klogere på både MVC og TDD. En sjov detalje han har bemærket er at alle i miljøet snakker om ”at hvis man nu er purist skulle man gøre sådan og sådan”, men han har umiddelbart ikke kunne finde nogen der direkte er purister inden for TDD.

Personligt kan jeg godt se anvendeligheden i TDD, men jeg mener helt klart at der er alt for meget hype om det, og at det bestemt ikke er alting det er velegnet til. Min holdning skyldes helt enkelt to ting; for det første at man ofte ikke har en god nok beskrivelse af hvad man skal udvikle til at man kan skrive en rigtigt god unit test, og for det andet at det ikke altid er noget godt kvalitetsmål. Med det mener jeg at det ikke er alting man kan teste ved hjælp af unit tests, både fordi eksempelvis usability slet ikke er noget mål for en unit test, men også fordi omkostningerne ved at skrive og vedligeholde tests kan være større end gevinsten. Dette er i nogen grad en pointe ”Joel on software” også har fremført, blandt andet ved en tale på Yale.

Jeg laver selv en del applikationer, hvor beskrivelserne er sparsomme, og udviklingen derfor ikke kan undgå at blive ”trial and error” baseret. Ikke forstået som i at der er masser af ”fejl” som sådan i koden (selvfølgelig er der også det), men fordi kundens ønsker ændrer sig markant i løbet af processen. Teoretikeren vil nok sige at så er analysen af projektet ikke god nok, en pointe der ikke går helt tabt på mig, men der er mange kunder hvor det simpelthen ikke er muligt i praksis. Let the religious battle between theory and pragma begin!

Min anden pointe med at det ikke er alting der lader sig unit teste, er selvfølgelig også et spørgsmål om vilje. Brugerflader og sprocs er vanskelige at teste, og selvom man gør sig en masse anstrengelser for at lave unit tests af disse ting er værdien mindre - i forhold til at kunne teste ”rene funktioner”, med kendt input og output. En sidste observation jeg har gjort mig, er at fejl oftere skyldes integrationsproblemer end direkte logiske fejl – og i systemer hvor det er tilfældet er integrationstests i virkeligheden mere formålstjenlige.

Selvom jeg måske nu lyder meget skeptisk, synes jeg at unit tests og TDD er rigtigt godt, til de ting det rent faktisk er opfundet til. Min indsigelse er blot imod den megen hype der er, da heller ikke det er nogen Silver bullet, og jeg føler at anvendeligheden af unit tests har det med at blive overdrevet.

Frameworks og tools – de små måske vigtige forskelle.

De fleste jeg har snakket med der har arbejdet med unit testing kender NUnit frameworket, som nok er det mest udbredte framework til unit testing i .NET. Frameworket er oprindelig portet fra JUnit og har efterhånden en del år på bagen.

Der findes imidlertid også to andre udbredte open source  alternativer som er MbUnit og XUnit – forskellene imellem de tre frameworks er relativt små, men som man siger ”god is in the details”.

MbUnit omtales som NUnit på crack, og er et framework der er udviklet til at være mere udvidelsesvenligt end NUnit er. Det er i dag nok det mest advancerede unit testing framework og giver blandt andet mulighed for at man via attributter beskriver data der skal passes til en testmetode, og derved kan den samme metode kaldes flere gange hvor forskellige grænseværdier testes.

[RowTest]
[Row("Christian", "123")]
[Row("Christian", "", ExpectedException = typeof(InvalidUserException))]
[Row("", "123", ExpectedException = typeof(InvalidUserException))]
[Row("Christian", "qwerty", ExpectedException = typeof(InvalidUserException))] 
public void CheckUserLogins(string name, string password)

Det har desuden også en feature til at rulle database ændringer tilbage ved hjælp af attributterne SqlRestoreInfoAttribute, RollBack og RestoreDatabaseFirst.

XUnit findes på codeplex, og det er udviklet med henblik på at skulle passe bedre ind i .NET miljøet, samtidig med der er ryddet op i attributter og assertions med henblik på at få pænere testkode. Jeg kan personligt virkelig godt lide at det gør brug af generics, og at det giver mulighed for at lave en slags aspect oriented programming.

Generics bruges blandt andet til fixture setup, sådan at man ved at bruge IUseFixture<T> kan passe klasser til ens testmetoder, som man så kan arbejde med.

public class MyTests : IUseFixture<MyFixture>, IDisposable
{    
    public void SetFixture(MyFixture data)    
    {                
        data.SomeMethod();    
    }
}

Aspect oriented programming fungerer ved at man laver ens egne attributter ved f.eks. at extende BeforeAfterTestAttribute, som blot er at overskrive et par metoder.

public class PrepreDatabaseAttribute : BeforeAfterTestAttribute
{    
    public override void Before(MethodInfo methodUnderTest)    
    {        
        // Do your pre-test stuff    
    }    
    public override void After(MethodInfo methodUnderTest)    
    {        
        // Do your post-test stuff    
    }
}

Udover et decideret testframework skal man også bruge et tool til at udføre ens tests og give overblik over hvad der går godt og hvad der fejler – de berømte grønne lamper man nyder at se lyse når man benytter TDD. NUnit har den fordel at der følger et lille separat tool med der kan lige præcis det, og som virker ganske fint til de flestes behov. Til XUnit er der et lignende tool under udvikling, men det er stadig eksperimentalt og virker ikke just som et færdigt tool endnu.

Alle 3 frameworks kan imidlertid også bruges sammen med TestDriven.NET og ReSharper , som begge er bedre bud hvis man vil have en ordentlig brugsoplevelse.

 TestDriven.NET er et add-in til Visual Studio, som giver mulighed for afvikling af unit tests, og er det tool flertallet bruger. Jeg må dog erkende at jeg synes TestDriven.NET er relativt dyrt, taget i betragtning af at det startede som et gratis værktøj og i bund og grund stadig er et simpelt add-in.

Resharper er også et Visual Studio add-in som man kan skaffe til rundt regnet samme pris som TestDriven.NET, men man får bare meget mere med i pakken, da det blandt andet også tilbyder hjælp til refactoring, formattering og kode analyse. Som det fremgår er jeg selv faldet lidt for ReSharper, selvom jeg var lidt skuffet over at det endnu ikke er klar i en .NET 3.5 udgave, så kodeanalysen fejler hårdt på LINQ queries o.lign. En ny version målrettet .NET 3.5 skulle dog være på trapperne, så jeg må bare leve med at slå kodeanalyse fra indtil da.

Test af sprocs – der hvor det bliver mere vanskeligt.

Når jeg nu tidligere har nævnt at jeg mener sprocs er vanskelige at teste, skylder jeg også at beskrive hvordan man kan gøre det - og uddybe hvad jeg mener med at værdien i mine øjne er mindre end ved test af mere isolerede funktioner.

Jeg læste i går en ganske god artikel i MSDN magazine omkring brugen af LINQ to SQL til test af sprocs. Der var egentlig ikke et perspektiv der i første gang havde slået mig, men det er egentlig klart at LINQ to SQL er godt til at teste sprocs på meget lettere vis end det var muligt i tiden pre-LINQ. Helt enkelt består sproc tests af.

·         Klargøring af database, så den er i en velkendt tilstand.

·         Afvikling af sproc.

·         Test af databasens tilstand er som ønsket.

De tre trin lyder simple nok, man har naturligvis en række komplikationer i forhold til det her med databasens tilstand. Det letteste er sandsynligvis at arbejde med en tom kopi af databasen, som gerne er separat fra ens anden test/udviklings database der typisk indeholder en røvfuld ”real world” data. Ved hjælp af LINQ kan man så faktisk med meget få linjer kode slette alle data i en tabel, og indsætte de data man ønsker som grundlag for testen.

Ligeledes kan man i LINQ afvikle den sproc der skal testes, og så er der egentlig ”bare” tilbage at teste databasens tilstand efterfølgende. Et godt tip fra artiklen er at hente alt data i en tabel, hashe det ved hjælp af eksempelvis en MD5 hash. Resultatet kan så meget enkelt sammenlignes med en hash som man udregner ved udformning af testen – noget der kan være en kende besværligt, da det at tage hashen første gang man afvikler koden kun beviser at resultatet er det samme ved efterfølgende afvikling og ikke nødvendigvis om det er korrekt.

Få overblik med Unit testing af sprocs

En anden måde at bruge unit tests på i forbindelse med sprocs, som jeg selv har været med til at implementere er at skrive en parser der undersøger hvilke sprocs man kalder fra sin kode og sammenligne med de sprocs der rent faktisk findes i databasen. Selvom det ikke er nogen test af funktionaliteten som sådan, kan det på store projekter bruges til at teste om de sprocs man kalder findes og omvendt om man har sprocs der ikke længere bliver brugt.

Lidt i samme boldgade kan man skrive en unit test der læser ens sprocs ud, og gemmer dem i databasen igen - giver dette en exception er det en god indikation af at sproc’en er knækket. Igen er det ikke nogen gylden løsning da man ikke finder logiske fejl og ikke engang alle slags fejl på den måde. Det er imidlertid et simpelt værktøj, som har sin berettigelse i at det kan give overblik og finde alvorlige problemer med meget simple midler.

Tags: ,

Livet vendt på vrangen og med nye udfordringer

by DotNetNerd 25. April 2008 22:12

Som livet dog pludselig kan blive vendt på hovedet 

Den sidste 1½ måned har været en rimelig stor omvæltning i mit liv, på både godt og ondt. Min kæreste og samlever igennem henholdsvis 4 og 3 år valgte at forlade mig, så pludselig fra den ene dag til den anden blev mig privatliv vendt på hovedet. Jeg vil ikke blotlægge mit blødende hjerte her på bloggen, men det skal nævnes da det har været en del af en masse forandringer der er sket på det seneste.

Heldigvis har arbejdet budt på andetledes positive tiltag, da jeg har fået ansvar for kvalitetssikring og herunder altså standardisering, tests og dokumentation. Det er nogle områder jeg glæder mig meget til at kunne fokusere mere på i den næste tid, samtidig med at jeg håber at kunne komme igang med Silverlight for alvor når nu version 2 kommer på gaden her en af de næste måneder.

F# præsentation for Aarhus .NET UserGroup

Som direkte konsekvens af at jeg var månedens blogger i marts, har jeg modtaget en henvendelse fra ANUG.dk, som gerne vil have mig til at lave en præsentation omkring F# til september. Det er helt sikkert også noget jeg ser frem til, da jeg længe har haft lyst til at prøve kræfter med at lave præsentationer/foredrag. Jeg tror det bliver rigtigt spændende og håber at både tilhørerne og jeg selv får en masse ud af det. Det er ihvertfald et emne jeg selv synes er enormt interessant for fremtiden, og så kan man da også håbe at kunne udvide sit netværk i den forbindelse.

Løbesæson

For godt et år siden blev jeg logget til at deltage i DHL staffetten 2007, selvom jeg aldrig havde tænkt så meget på at begynde at løbe. Pre foråret 2007 sagde jeg altid at jeg ikke løb med mindre der var nogen efter mig, og selv der var det tvivlsomt om jeg egentlig gad :) Det viste sig imidlertid at jeg blev lidt bidt af det - så nu er det en motionsform jeg nyder at kombinere med at træne i motions center. Jeg er afgjort kun hyggeløber, idet jeg begrænser min "løbesæson" til at være nu her imens vejret er rart, og på den måde håber jeg også at undgå at køre træt i det. I næste uge er det så eventyrløbet jeg vil prøve at kaste mig ud i, og jeg håber at få bedre vejr til det end tilfældet var sidste år til staffetten hvor det var regnvejr og bidende koldt.

Tags:

Andenplads ved E-handelsprisen 2008 og FLOT fremskridt

by DotNetNerd 27. March 2008 21:25

Andenplads ved E-handelsprisen 2008

Idag blev e-handelspisen for 2008 uddelt, hvor byggecity.dk som vi har udviklet var nomineret, hvilket vi allerede var glade for. Derudover blev det til en flot 2. plads i kategorien nystartere. Det er et projekt vi fortsat ser frem til at arbejde videre med, og hvor vi har nogle spændende initiativer i støbeskeen, så at det allerede har fået sådan en erkendtlighed er bestemt en behagelig overraskelse.

FLOwerTracker

I fritiden skrider det desuden også fremad med mit FLOwer Tracker projekt, som har fået egne domæner på flowertracker.dk og flowertracking.dk. I samme ombæring blev sitet flyttet til min egen virtuelle server, som jeg er blevet rigtigt glad for (solarvps.com). Projektet som sådan er også blevet udvidet en anelse, med udvidede muligheder for data udtræk, så det begynder efterhånden at ligne et mere komplet produkt - selvom der er passer af udvidelser på vej.

JoelOnSoftware om browserkompatibilitet

Joel har igen begået et fantastisk blogindlæg, hvor jeg synes han virkelig rammer sømmet på hovedet. Denne gang er det omkring hele den her browser krigszone som vi udviklere står midt i, og alt for mange vælger at udtale sig om uden rigtigt at have forstået problemet. Indlægget kan læses her: http://www.joelonsoftware.com/items/2008/03/17.html

Tags:

F# og imperativ programmering

by DotNetNerd 19. March 2008 23:50

Som jeg tidligere har nævnt er en af de helt store styrker ved F# at det giver mulighed for at kombinere forskellige stilarter, og jeg skylder derfor at runde imperativ programmering, som nok i virkeligheden er den programmeringsform de fleste udviklere er bekendt med.

Imperativ betyder påbud og inden for grammatik er det den form at et verb vi på dansk kalder bydeform (eks. "syng!"). Imperativ programmering vil derfor sige programmering hvor ens statements går på "hvordan" en opgave løses, hvorimod funktionel programmering handler mere om "hvad" der skal gøres.

Selvom F# i udgangspunkt er et funktionelt sprog der søger at få folk til at bruge immutable datastrukturer, kan det nogen gange være mere intuitivt at arbejde med imperative statements som loop strukturer og mutable data. Der kan selvfølgelig også nogen gange være en masse performance at hente ved ikke at skabe en masse objekter men istedet blot ændre en værdi.

Looping and iterating over data

Et helt basalt loop ligner noget man kender fra andre sprog og ser ud som herunder.

let PrintValues1To10 =
  for i = 0 to 10 do
    printfn "Value: %d" i

PrintValues1To10

På samme måde kan man desuden skrive et while loop sådan her.

let PrintNamesAndCities =
  for (name, city) in [("Christian", "Odense"); ("Henrik", "Kerteminde")] do
    printfn "%s %s" name city

PrintNamesAndCities

Mutable data og while loops

While loops som man kender dem findes naturligvis også, men disse bruges oftest sammen med mutable data hvis man tænker over det. Et typisk scenarie er at man laver en udregning og gentager denne indtil en given variabel har en værdi der tilfredsstiller et eller andet boolsk udtryk. Et eksempel på anvendelse at et while loop og mutable data kunne eksempelvis være.

let PrintWhileLessThan10 =
  let mutable i = 0
  while (i<10) do
    printfn "Value: %d" i
    i <- i+1

PrintWhileLessThan10

Det ovenstående eksempel viser den mest brugte måde at arbejde med mutable typer, men ligesom man i andre sprog kan arbejde med mutable reference typer kan man også i F# ved hjælp af keywordet ref og operatorerne ! og :=. På den måde kunne ovenstående stump kode have været skrevet sådan her, med samme overordnede resultat.

let PrintWhileLessThan10 =
  let i = ref 0
  while (!i<10) do
    printfn "Value: %d" !i
    i := !i+1

PrintWhileLessThan10

Imperative collections

Udover de datastrukturer jeg har set på tidligere her på bloggen kan man desuden også arbejde med de collection klasser der findes i .NET frameworket, som er imperative af natur. Disse collections bruges på samme vis som du sikkert er vant til men System.Collections.Generic.List<'a> bruges normalvis via aliaset ResizeArray, som er standard i F# fordi det er mere sigende for hvad strukturen er beregnet til.

let names = new ResizeArray<string>()

for name in ["Jens"; "Frans"; "Erik"] do
  names.Add(name)

printfn "Navn: %s" names.[1]

Exception raising og handling

En anden karakteristisk egenskab det går igen i imperative sprog er exception handling. Selvom det bygger på den måde exception handling fungerer på i .NET frameworket fungerer det en smugle anderledes i F#.

Hvis man vil raise en exception kan det gøres sådan her:

raise (System.InvalidOperationException("Man kan jo ikke dividere med 0 vel!"))

Der findes dog også en generel måde at raise exceptions på ved at skrive eksempelvis sådan her.

failwith "Man kan jo ikke dividere med 0 vel!"

Som medfører at en Microsoft.FSharp.Core.FailureException kastes. Den findes også i en failwithf der tager stringformat argumenter ligesom printf.
Specifikt til argument exceptions er der en forkortet udgave der kaster en InvalidArgumentException.

invalid_arg "argument må ikke have negativ værdi"

På den anden side af hegnet skal man jo også kunne håndtere exceptions. Dette fungerer som en kombination imellem en try catch som de fleste kender den og et udtryk til pattern matching.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
with
  | :? System.InvalidOperationException as err -> printfn "Grebet ud: %s" err.Message

Ellers hvis man ønsker at gribe alle exceptions kan det gøres sådan her.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
with
  | err -> printfn "Message: %s" err.Message

Og finally findes naturligvis også til at sørge for at ressourcer disposes korrekt - og den ligner sig selv som man kender den.

try
  raise (System.InvalidOperationException("Fejl nu bare"))
finally
  printfn "Finally kaldt"

Man kan dog ikke kombinere disse som i andre .NET sprog da en try-with-finally konstruktion ikke er understøttet, idet det ikke findes i OCaml. Det man normalt gør istedet er at bruge enten en "use" binding eller et "using" scope istedet.

let WriteToFile() =
  use output = File.CreateText(@"data.txt")
  output.WriteLine("This is nice")

 eller som using

let WriteToFile() =
  using (File.CreateText(@"data.txt")) (fun output ->
    output.WriteLine("This is nice"))

 

Tags:

F# interaktiv, pattern matching og active patterns

by DotNetNerd 23. February 2008 17:46

Interaktiv eksekvering

Interaktiv eksekvering er en feature som F# tilbyder der giver mulighed for at afvikle kode som scripts. Dette giver mulighed for at skrive kode på en behagelig måde, hvor man undgår hele tiden at skulle igennem en kode-compile-run cyklus. En almindeligt anvendt teknik er at anvende en scriptfil som "scratch pad", hvor man kan teste små stykker kode løbende.

For at udnytte dette skal man blot åbne F# interactive igennem Tools -> Add-in Manager og lave en fsx fil. Her skriver man så sin kode og når der er en del man ønsker at eksekvere markerer man den og trykker Alt + Enter. Dette gør at man meget hurtigt kan teste sin kode, uden at skulle compile, sætte et breakpoint og debugge indtil man er fremme til det sted i koden man er interesseret i.

Pattern matching

En interessant ting man kan starte ud med at prøve af - f.eks i F# interactive - er pattern matching, som er en feature der ikke er set før i .NET sprog, men som findes i andre miljøer. Pattern matching giver en meget kompakt måde at styre program flow på, lidt i stil med at bruge case sætninger i struktur, men langt mere anvendeligt og kraftfuldt.  Et super simpelt eksempel kan være at man gerne vil afvikle noget kode ud fra hvad værdi en streng har:

let value = "a"

match value with
| "a" -> printfn "The value was an a"
| "b" -> printfn "The value was a b"
| _ -> failwith "Unknown value"

Som det fremgår er syntaksen meget kompakt, og let at læse. Underscoren i den sidste linie betyder at hvilken som helst anden værdi vil blive håndteret, lidt ligesom default i en case hvis man vil sammenligne det med noget man kender fra C#/VB. En vigtig ting man skal vide er at et pattern match altid skal være udtømmende. Det vil sige at det samlet set skal kunne håndtere alle mulige værdier for at det validerer. Desuden afvikles koden ved at værdien matches imod mønstret linie for linie indtil der findes et match. Så hvis man laver et match der udelukker et efterfølgende vil man få en warning idet koden aldrig vil kunne blive ramt.

En anden anvendelse af pattern matching er til at opløst tubler som ses herunder. Nu begynder vi at komme ud i nogen scenarier der viser at pattern matching er mere anvendelige end case sætninger, og at de er stærke i samspil med funktionelle data strukturer.

let value = ("b", "a")

match value with
| ("a", "b") -> printfn "The values were a and b"
| ("b", _) -> printfn "The first value was b"
| _ -> failwith "Unknown value"

Der kan matches på mange forskellige måder men en anden meget anvendt operator :? gør det muligt at matche på typer. Her er det dog vigtigt også at bemærke at dette kræver en box operation, som der fremgår.

let value = "2"

match box value with
| :? System.Int32 -> printfn "The values was an integer"
| :? System.String -> printfn "The value was a string"
| _ -> failwith "Unknown value"

Active patterns

Active patterns er en teknik der gør det muligt at skrive mere advancerede patterns til brug sammen med mere komplekse datastrukturer eller til at lave mere komplek matching. I eksemplet herunder ses et active pattern der matcher ud fra et regular expression og returnerer en option sequence af de værdier der blev matchet ved at eksekvere det angivne regex.

let (|ParseRegex|_|) regex str =
  let regex = new System.Text.RegularExpressions.Regex(regex)    
  let matches = regex.Matches(str)    
  if matches.Count > 0 then        
    Some { for x in matches -> x.Value }    
  else        
    None

Dette active pattern kan derefter bruges på følgende måde sammen med pattern matching til eksempelvis at udskrive alle tal i en streng. Underscoren i deklerationen af dette active pattern betyder at mønstret er ufuldkomment, hvilket vil sige at det kan returnere None.

let PrintNumbers str =
  match str with
  | ParseRegex "\d" st -> Seq.iter(fun x -> printfn "Number found: %s" x) st
  | _ -> printfn "No numbers"

PrintNumbers "b123"

Alternativt kan active patterns bruges over eksempelvis discriminated unions. Et meget anvendt eksempel rundt omkring på nettet har været et discriminated union over et binært træ. Eksemplet kan ses herunder og det representerer helt enkelt et træ, hvor hvert element kan være enten en knude eller et blad - hvor knuder består af 2 elementer.

type BinaryTree<'a> =    
  | Leaf of 'a    
  | Node of BinaryTree<'a> * BinaryTree<'a>

Udfra dette kunne et active pattern eksempelvis bruges til at returnere om en XmlNode er en node eller et blad.

let (|Node|Leaf|) (node : #System.Xml.XmlNode) =    
  if node.HasChildNodes then        
    Node (node.Name, { for x in node.ChildNodes -> x })    
  else        
    Leaf (node.InnerText)

Dette kunne så bruges til at lave forskellige matches, og eksempelvis rekursivt udskrive noderne indenteret ligesom i xml dokumentet.

let PrintXml node =    
  let rec PrintXml indent node =        
    match node with        
    | Leaf (text) -> printfn "%s%s" indent text        
    | Node (name, nodes) ->            
      printfn "%s%s:" indent name            
      nodes |> Seq.iter (PrintXml (indent + "    "))    
  PrintXml "" node

Givet et xml dokument over ansatte i en lille IT virksomhed kunne man så benytte funktionen til at udskrive indholdet pænt sådan her.

let doc =    
  let xmlDoc = new System.Xml.XmlDocument()    
  let text = "
<employees>    
  <programmers>
    <junior>10</junior>
    <senior>8</senior>
  </programmers>
  <designers>3</designers> 
</employees>"
  xmlDoc.LoadXml(text)    
  xmlDoc
PrintXml (doc.DocumentElement :> System.Xml.XmlNode)

Tags:

Feed-Me.dk release og Lang.NET inspiration

by DotNetNerd 22. February 2008 19:49

Feed-me.dk release 

Det seneste års tid er jeg i stor stil røget med på rss bølgen, og er begyndt at abonnere på en række feeds for at følge med i diverse nyheder - især inden for .NET udvikling. Jeg er dog tit løbet på det problem at der er feeds som indimellem indeholder nogle virkelig interessante indlæg, men som desværre hovedsageligt drukner i personlige historier, som jeg er knap så interesseret i. Jeg har derfor nu lavet en service som jeg stiller gratis til rådighed på http://www.feed-me.dk, hvor det er mulige at sammensætte et feed der er kombineret af andre feeds, og filtreret ud fra nøgleord man indtaster som har ens interesse. Man kan desuden selv vælge om man vil have feedet i RSS eller Atom format, ved at angive dette som en del af url'en i et REST format. Eksempelvis har jeg lavet et udviklings feed som kan ses her: http://www.feed-me.dk/feed.svc/UdviklingsDemo/rss - hvor url'en viser at det sammensatte feed er navngivet UdviklingsDemo og at jeg vil se den i rss format.

Da servicen er gratis håber jeg at brugerne er så flinke at holde øje med mine google reklamer, og klikker på dem de synes er interessante, og eventuelt bruge den søgebar jeg har inkluderet i bunden. Ideen er at jeg vil give 20% af de penge jeg eventuelt tjener til kræftens bekæmpelse, idet det er en sygdom jeg selv har haft tæt inde på livet. Skulle du finde servicen interessant men synes der mangler en eller anden feature må du meget gerne skrive om dit ønske, da jeg gerne udvider den. Som det tydeligt fremgår af siden er jeg ikke den store designhaj, men pointen er også klart at lave en teknisk velfungerende løsning, så det er heller ikke mange minutter der er spildt på design.

Lang.NET

En af de nyheder jeg senest er faldet over ved at abonnere på blogs rundt omkring er, at der for nylig blev afholdt Lang.NET symposium (http://langnetsymposium.com/talks.asp), hvorfra der er udgivet en række interessante webcasts. En af de casts jeg især synes var interessant var Eric Meijer der talte om Volta. Jeg synes det er et virkeligt interessant eksperiment, og håber da meget det kan udvikle sig til et alternativ til den måde man udvikler applikationer på idag. Kort fortalt går Volta ud på at man koder en applikation som single tier, og vilta frameworket kan så ved hjælp af MSIL rewriting splitte applikationen i flere lag, lave asynchronous kald og sørge for at oversætte koden så den kan afvikles i det miljøet tilbyder i et givent scenarie. Noget der især virker som sort magi på mig er tanken om at frameworket kan omdanne kode i et CLR sprog til javascript - dette har naturligvis sine begrænsninger men er alligevel ganske fascinerende.

Udover Volta var der også andre interessante taler af blandt andet danske Anders Hejlsberg, der talte om C# 3.0 og kort kommer ind på nogen af de ting de har på tegnebrættet til version 4.0 eller hvad den nu kommer til at hedde. Også F# som jeg har rodet lidt med i fritiden her på det sidste var der et par taler omkring - hvor den ene dog mest omhandlede parsere og leksere, som er en af de ting F# tilbyder nogle specielle features til at understøtte.

Tags: , ,

F# funktionelle typer og objekt-orienteret programmering

by DotNetNerd 27. January 2008 17:51

F# funktionelt eller objektorienteret?

En stor del af dem der har hørt om F# har hørt at det er et funktionelt programmeringssprog, hvilket er sandt nok - det er bare ikke udelukkende funktionelt. Faktisk understøtter sproget i lige så høj grad at man kan programmere objekt orienteret med imperative teknikker. Det er faktisk netop derfor F# er brugbart i ”den virkelige verden” i modsætning til eksempelvis Haskell der stort set udelukkende benyttes til undervisning i praksis.
Jeg vil i dag kigge på forskellige teknikker til at arbejde med typer, først med udgangspunkt i funktionel programmering og sidenhen med fokus på objektorientering.

Simple typer til funktionel programmering

I funktionel programmering arbejder man meget med objekter på to måder, nemlig med records og discriminated unions. Records svarer til det man ellers kalder en entitet, som er et helt simpelt databærende objekt.

type Employee =
  { Name: string;
    HiredDate: System.DateTime; }

Som så kan bruges således, hvor type udledes via ducktyping - if it walks like a duck and it talks like a duck, its probably a duck.

let employee1 =
  { Name = "Christian";
    HiredDate = System.DateTime.Parse("11/07/2003") }

Eller således.

let employee2 =
  { new Employee
    with Name = "Hans"
    and HiredDate = System.DateTime.Parse("11/07/2003") }

En smart feature der skal nævnes I den forbindelse er at det er nemt at klone records, så hvis man skal lave en ny record der næsten er magen til en anden kan man eksempelvis gøre det sådan her.

let employee1Cloned = { employee1 with HiredDate = System.DateTime.Parse("15/10/2005") }

Discriminated Unions bruges til at modellere et endegyldigt og lukket sæt af muligheder der ikke kan ændres. Man arbejder typisk med med discriminated unions ved først at definere nogle type forkortelser, som ganske enkelt består i at man giver en eksisterende type et alias.

type Route = int
type Make = string
type Model = string

Derefter kan man så bygge sit discriminated union ved hjælp af forkortelserne sådan her.

type transport =
  | Car of Make * Model
  | Bicycle
  | Bus of Route

Som man forhåbentlig kan se ud af det her er det en meget præcis måde at modellere del slags data på. Ud fra ovenstående kan man nu arbejde med typerne sådan her.

let myMeansOfTransportation = [ Car("Skoda", "Fabia"); Bicycle; Bus 128 ]

Det har muligvis allerede slået dig at den her måde at modellere på minder om ”enumerations på speed”, og rent faktisk opbygges enums i F# sådan her.

[<Struct>]
type Shape =
  | Circle = 1
  | Rectangle = 2
 

Objektorienteret programmering

Den vigtigste egenskab ved objekter er at de indkapsler mutable værdier, og bruges dermed til at indkapsle tilstand - således at omdrejningspunktet for koden er tilstands checks og tilstands ændringer.
Som jeg skrev i sidste post er værdier som udgangspunkt immutable i F#, hvilket er en stor styrke idet man derved ligger op til at tænke i at skrive kode der ikke afhænger af tilstandsstyring hvilket hurtigt kan blive rodet og svært at vedligeholde. Det kan imidlertid være nødvendigt med mutable værdier, og i nogen tilfælde er det med til omvendt at gøre kode lettere at læse og mere effektivt.
Helt enkelt gøres en værdi mutabel ved hjælp af nøgleordet ”mutable” og den kan derefter modificeres ved hjælp af operatoren <- på samme måde som man kender der fra VB og C# med = tegnet.

let mutable n = 0
n <- 6
printfn "%d" n

En anden velkendt teknik er at anvende mutable reference celler ved hjælp af nøgleordet ref og operatorerne := til at sætte en værdi og ! til at hente den, som du kan se brugt her.

let n = ref 6
n := 7
printfn “%d” !n

Andre uundværlige teknikker fra objektorienteret programmering er boxing/unboxing af værdityper og upcasting/downcasting imellem typer. Boxing af en type vil sige at wrappe dem til objekter, således at de kan gives til metoder der tager typen object.

let o = box 6
let i = unbox<int> o  // kan også skrives som let i = unbox o : int

Upcasting bruges til at caste en type til en type den arver fra.

let stringObject = ("qwerty" :> obj)

Downcasting bruges til at caste en variable til en mere nedarvettype som den er en instans af.

let myString = stringObject  :?> string
 

Members - objektets ansigt udadtil

Som tidligere nævnt er indkapsling en nøgleegenskab i objektorienteret programmering. Ligesom i andre .NET sprog  kan værdier pyntes med modifieren private hvis de ikke skal være tilgængelige udefra. Derudover kan man naturligvis lave members der stilles til rådighed for andre som vi nu skal se nærmere på.
Mutable properties er nok den mest anvendte membertype, idet de helt enkelt bruges til at stille data til rådighed. En property ser sådan her ud i F#.

let mutable text = ""
member t.Text
  with get() =
    text
  and set v =
    text <- v

Indexers bruges på samme måde, men bruges til at tilgå data som en collection af data der tilgås via en eller flere indeks parametre.

let elems = [| "A"; "B" |]
member t.Item
  with get(id) = elems.[id]
 

Argumenter der holder

I F# kan man benytte sig af teknikker som optionelle- og navngivne argumenter. Optionelle argumenter angives ved hjælp af ? hvilket gør at værdien bliver en option og den kan altså dermed være ingenting.
defaultArg funktionen bruges til at trække værdien ud eller alternative en default værdi hvis optionen er None.

type LabelInfo(?text:string) =
  let text = defaultArg text ""

Named arguments er en anden teknik der relaterer sig til at arbejde med argumenter. Ved at bruge named arguments angiver man værdien for et argument præcist frem for ud fra argumentets placering. En smart feature i den forbindelse er at man kan angive argumenter som der ikke nødvendigvis er en constructor til så længe typen har en public property til den angivne parameter.

let form = new Form(Visible=true, TopMost=true)
 

Implementation af interfaces

Nu er det vidst ved at være tid til at se på hvordan man implementerer en klasse som vi kender den fra VB eller C#. For at starte fra bunden ses her hvordan man deklarerer et interface.

type IShape =
  abstract Contains : Point -> bool

Ovenstående interface kan derefter implementers af en funktion på følgende måde.

let Circle() =
  { new IShape with
    member x.Contains(p:Point) = true
  }

Teknikken der er anvendt her kaldes object expressions og det er en simpel teknik der anvendes ofte når man implementerer interfaces eller extender typer.
Definitionen af en object expression er sådan her.

{ new Type optionalle-argumenter with
            Member-definitioner
  Optionalle-ekstra-interface-definitioner }

En implementation af et interface på en konkret type som man nok oftere vil bruge den kan se sådan her ud.

type MutableCircle() =
  let mutable center = Point(x=0, y=0)
  member c.Center with get() = center and set(v) = center <- v
  interface IShape with
    member c.Contains(p:Point) = true
 

Brug af delvist konstruerede typer

Delvist konstruerede typer er typer der har abstrakte members, som skal implementeres af en specialiseret type. Alternativt kan man angive en default implementation som kan overskrives af den type der nedarver.

type Formatter() =
  abstract Format : string -> string
  abstract ReplaceWhitespace : string -> string
  default x.ReplaceWhitespace(s:string) = s.Replace(" ", s)

En sådan klasse kan implementers ved hjælp af object expressions.

let myFormatter =
  { new Formatter() with
    member f.Format(s) = s }

Eller den kan ligeledes implementeres via implementation inheritence.

type HtmlFormatter() =
  inherit Formatter()
  default f.Format(s) = s

I forbindelse med implementation af en given member kan nøgleordene override og default bruges til at indikere om man overskriver en metode der har en implementation i forvejen eller ej.

Statiske metoder og extension methods

Statiske metoder i F# implementeres ikke på en klassen, men på et module. Ønsker man at en statisk metode skal ligge på en klasse (eller dele navn med den om man vil) skal modulet dekoreres med en CompilationRepresentation attribute.

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module MyOperations =
  let MyStaticMethod(i:int, i2:int) = "Taller er " + (i + i2).ToString()

En relateret teknik er deklerationen af extension methods som også for nylig er kommet med i VB og C#.
En extension method i F# deklareres som en del af modulet med følgende syntaks.

type System.Int32 with
    member i.Add(i2:int) = MyStaticMethod(i, i2)

For at bruge extension metoden skal man derefter blot åbne modulet, på samme måde som i VB.

open MyOperations

let i = 1
let s = i.Add(12)
 

Afrunding - muligheder for fremtiden

Jeg håber at have illustreret med ovenstående gennemgang at man kan bruge F# til at arbejde fuldt ud objekt-orienteret, på holde med det man kan i andre .NET sprog. Netop det at man kan mix and matche imellem paradigmer er efte rmin mening den helt store styrke ved F#. Jeg er selv kun ved at komme igang med sproget og kaster mig i næste uge ud i at lave mit første modul i sproget, som bliver et stregkodeparser til mig FLOwer Tracker system. Jeg håber det har givet andre lyst til at prøve kræfter med sproget som jeg nok ender med at skrive meget mere om med tiden efterhånden som det vinder frem og bliver kørt ind i .NET frameworket fuldt ud som planen er fra Microsofts side.

 

Tags:

F# igang med funktionel programmering

by DotNetNerd 29. December 2007 18:46

F# - brugbar funktionel programmering

For en god uges tid siden dumpede bogen "Expert F#" endelig ind af min brævsprække - noget jeg har glædet mig til i et stykke tid, da jeg har hørt mange spændende ting om sproget. Inspireret af at jeg engang læste at man bør lærer sig et nyt programmeringssprog hvert år synes jeg det var det perfekte næste skridt for mig. Jeg har absolut ingen erfaring med funktionel programmering udover det jeg har rodet med LINQ - hvilket ikke er helt "rigtig" funktionel programmering men rettere funktionel funktionalitet indarbejdet i et Objekt Orienteret sprog.

Idet jeg næppe er den eneste der ikke har rodet med funktionel programmering, da det hovedsageligt har hørt hjemme på universiteterne hidtil, vil jeg skrive en smugle om nogen af de basale ting i funktionel programmering og F#. Hvis du tænker "hvis det hvedsageligt hører hjemme på uni, hvad kan jeg så bruge det til i praksis", så er pointen netop at F# udover at være et funktionelt sprog, også giver mulighed for at tilgå .NET frameworkets mange herligheder, og arbejde imperativt hvis man vil. Jeg tror F# har gode muligheder for at vinde frem netop
af den årsag, da det tilbyder fantastisk ekspressivitet sammen med adgang til de ting vi bruger .NET frameworket til allerede.

Lidt basics

Lidt ligesom der i VB findes option strict og explicit er der i F# "#light", som aktiverer det der kaldes light syntaks. Med andre ord slipper man for at skrive en masse ting og afslute linier manuelt osv. Eller kort sagt, bare skriv det øverst i din kode!

Kommentarer i F# minder langt hen ad vejen om den måde man skriver dem på i C#, med undtagelse af flerlinies kommentarer.

// Her er en enlinies kommentar.

(* Her står der en
flerlinies kommentar *)

///<summary>Xml kommentarer ligner også sig selv som i C#</summary>

Lidt ligesom man har Dim, var o. lign. ord der deklarerer en variabel har man i F# ordet "let" der definerer starten på en funktion. For at illustrere og vise hvordan scope fungerer er her et eksempel:

let powerOfTwo number
  let result = number * number
  result

Her definerer man en funktion der hedder powerOfTwo, som tager et argument "number". Funktionen består af en lokal funktion der er tallet ganget med sig selv. Man kan også se at inferens af typer bruges i meget vid udstrækning og at indrykning bruges til at afgrænse scope ligesom i (Iron)Python.

For at undgå at skulle ud i den helt langt gennemgang af simple typer og operatorer vil jeg nøjes med som udgangspunkt at sige at de langt hen ad vejen er de samme som i C# og ellers er der masser af steder man kan finde oversigter over dem via vores allesammens bedste ven google.

Det er vigtigt at vide at operatorer er unchecked. Operationer der giver overflow kaster altså ikke exceptions men de wrappes istedet. En anden ting der er vigtig at forstå er at de fleste typer er immutable med mindre det explicit angives at de skal være mutable. Det giver en række fordele, da man derved kan være sikker på at en værdi ikke ændres "bag om rykken" på en. Noget der især er rart når man arbejder trådet da man så ikke skal bekymre sig så meget om "concurrent access".

Grundlæggende data strukturer

Fleksible datastrukturer er en af hovedingredienserne i et funktionelt sprog, da de gør det muligt at skrive meget ekspressiv kode til at arbejde med mængder af data.

Tuple:

Tupler bruges til at returnerer flere værdier fra en funktion, som ikke nødvendigvis er af samme type. En tupel angives helt enkelt med en parentes hvori værdierne adskilles af en komma. En funktion der tæller ord kunne for eksempel returnere, totalt antal ord og antallet af unikke ord.

let wordCount = (10, 8)

fst og snd er keywords der bruges til at anvende det første og andet element i en touple - og dermed til at arbejde med par.

let totalWordCount = fst wordCount

En anden mulighed er at decompose tuplen i flere værdier.

let totalWordCount, totalUniqueWordCount = wordCount

Array:

Arrays kender de fleste nok ganske godt så dem vil jeg gå lidt let hen over. En vigtig ting at nævne er dog at arrays er den eneste af de collection strukturer jeg skriver om her der er mutable. Et array i F# defineres således:

let myArray = [|1;2;3;4;5|]

En anden funktion der er værd at nævne er at man kan definere et litteral byte array som:
let myArray = "MAGIC"B // Det svarer til [|77uy; 65uy; 71uy; 73uy, 67uy|]

Array slicing som ellers er en ting man godt kan savne lidt i andre .NET sprog kan desuden laves således.

let slicedArray = myArray.[1 .. 3]

List:

List i F# er en implementation af en singularly linked list som er en struktur der læses hurtigt hvis man læser elementerne igennem fra
start til slut.
 
let oneHalfOfTheFamily = ["Claus";"Lena";"AC"]
let anotherHalfOfTheFamily = ["Allan";"Janni";"Peter";"Jacob"]
let bothHalvesOfTheFamily = oneHalfOfTheFamily @ anotherHalfOfTheFamily

Her set man to lister blive oprettet og smeltet sammen. Det er vigtigt at huske at lister er immutable, så efter dette er sket er værdierne af de to første lister uændrede.

Set:

Sets indeholder ordnede lister hvor der kun kan være 1 af hver værdi, og sets er case sensitive. Et eksempel illustrerer meget godt hvordan den bruges.

let myset = Set.of_list ["BAC";"ABC";"ABC"]

Vil give en Set<string> med indholdet ["ABC";"BAC"]

Sets kan laves til lister eller laves fra lister ved hjælp af to_list og of_list

Option:

Options bruges til at beskrive en struktur der enten har en værdi eller er None. Keywordet her er "Some" og kan bruges således.

let childAndParents = [ ("Jens", Some("Ib", "Hanne"));"Jonas", None]

Options har funktioner som get der returnerer værdien af en some option og is_option der returnerer true for en some option.

Sequence:

Sequences er en abstraktion over datastrukturer der kan læses sekventielt og er alt der implementerer IEnumerable, som man kender det fra andre .NET sprog. I F# har sekvenser deres eget keyword som er seq. Det vil sige alle typer der er IEnumerable kan arbejdes med som sekvenser, det inkluderer arrays, lists osv. En smart F# feature er at man kan beskrive ranges af værdier i sekvenser på følgende måde.

let myNumbers = seq {0 .. 5}

Som vil give en sequence af værdier fra 0 til 5. Denne liste er lazy således at værdierne ikke genereres før de skal bruges. Dette er meget vigtigt hvis man skal arbejde med rigtigt lange sekvenser. Man kan desuden definere et interval i sevensen således.

let myNumbers = seq {1 .. 2 .. 6}

Som vil give værdierne [1;3;5]

Eller man kan definere en sequence ud fra f.eks. et for expression:

let powersOfTwo = seq { for i in 0 .. 10 -> i*i }

List og Seq indeholder desuden en række funktioner som eksempelvis map, iter, filter, to_array og of_array. De først nævnte gør det nemt at arbejde med strukturerne ved at passe en funktion ind.

powersOfTwo.iter(fun number -> Printf.printf "Number = %s\n" (number)

Functionelle værdier

En anden vigtig bestantdel i et funktionelt sprog er naturligvis muligheden for at arbejde med funktionerne. En række metoder som for eksempel map og iterate der findes på blandt andet List og Sequence tager imod en funktion som argument. Map bruges til at omforme alle elementer i strukturen og iterate bruges til at iterere strukturen og udføre funktionen på hvert element. En funktion kan som shorthand skrives som:

let namesWithH = Names.Filter(fun name -> name.StartsWith("J"))

Man har desuden mulighed for at "pipe" funktioner, sådan at en funktion kaldes med retur værdien fra den forrige funktion. Piping er en god
måde at gøre kode mere let læseligt på da det kan læses fra højre mod venstre og ikke indefra ud som man ellers tit ender med at skulle.


let PrintNamesWith prefix =
  NamesWith(prefix) |> List.iter(fun name -> Printf.printf "Name = %s\n" (name))


Man kan også arbejde med sammensatte funktioner og partiel applikation. Disse to teknikker viser hvor fleksibelt sproget er når man arbejder med funktioner.

let getNames s = String.split [';'] s
let countNames = getNames >> List.filter(fun (name:string) -> name.StartsWith("M")) >> List.length
let NameCount = countNames "Mia;Christian;Mig"

Eksmeplet viser hvordan man givet en funktion "getNames", kan definere en ny funktion countNames, som er en sammensætning af denne, List.filter og List.length - som derved kan bruges til at tælle antallet af navne i en semikolon separeret streng. F# har en meget powefull engine til at sammensætte effektive funktioner på denne måde.


let shift (x, y) (x1, y1) = (x1+x, y1+y)
shiftright = shift(1,0)

Dette eksempel viser helt enkelt at man kan definere en ny funktion ved at kalde en anden funktion med kun nogen af de argumenter den kræver. Dette giver mulighed for at være meget beskrivende i sin kode ved at lave en række partielle funktioner der løser specifikke opgaver på baggrund af en mere generel funktion.

Konklusion

Jeg håber ovenstående givet et godt indblik i nogle af de mest basale strukturer og teknikker der anvendes i F# i forbindelse med funktionel programmering. Som tidligere nævnt er F# ikke et "rent" funktionelt sprog så man kan også arbejde med imperativ programmering i sproget. Det kan være det bliver et emne jeg tager op senere. Selvom jeg er ny indenfor funktionel programmering synes jeg hurtigt man får et indtryk af hvor ekspressiv kode man kan skrive og at det er vejen frem især hvis man skal kode en applikation til et trådet miljø.

Tags:

Opsætning af IIS 7.0 og Windows Communication Foundation i Vista

by DotNetNerd 16. December 2007 14:50

Jeg opdagede idag at det er knap så "lige ud af boksen" som man kunne ønske sig at afvikle ASP.NET og Windows Communication Foundation services under Vista og IIS 7. Man kan kun undre sig over at ihvertfald ASP.NET ikke automatisk installeres ved installation af IIS, men det er åbenbart ikke tilfælder. Det lykkedes dog efter at have rodet lidt at få det til at virke og jeg vil derfor lige skrive en guide hvis andre skulle støde på samme problem. 

Installation af IIS og ASP.NET på Windows Vista

For at kunne afvikle en ASP.NET applikation skal man først installere IIS og den tilhørende ASP.NET komponent. Dette kræver administrator rettigheder og gøres ellers ved at:

  • Gå til kontrolpanel -> Programmer og funktioner.
  • Herfra vælger du "Slå windows funktioner til eller fra" i sidemenuen til venstre i vinduet.
  • Vælg internet Information Service og udvid punktet.
  • Udvid "værktøjer til webmanagement" og "kompatibilitet med IIS 6 management".
  • Vælg "Kompatibilitet med IIS-metabase og IIS 6-konfiguration".
  • Udvid også "World wide web services" og Funktioner til programudvikling.
  • Vælg ASP.NET checkboksen.

Du kan nu afvikle ASP.NET applikationer ved at oprette dem på almindeligvis via IIS management værktøjet - eller bruge default sitet ved at smide det i inetpub/wwwroot.

Installation af WCF service modellen

For at kunne afvikle en Windows Communication Foundation service skal service modellen registreres.

Dette gøres ved at:

  • Åben en kommandoprompt med admin rettigheder.
  • Gå til %Windows%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\
  • Check status ved at skrive ServiceModelReg -vi og se om service modellen allerede er installeret.
  • Er den ikke installeret skriv ServiceModelReg -i og så skulle modellen blive installeret.

Og nu kan du så også afvikle en Windows Communication Service.

Lige for en god ordens skyld skal det siges at for at hoste en WCF service under IIS 7 skal man blot smide en svc fil med følgende indhold i roden af sitet.

<%@ ServiceHost Language="C#" Debug="true" Service="Syndication.FeedService" %>

Hvor servicen skal pege på klassen der implementerer din service. Dll'en skal ellers bare ligge i en bin mappe som den plejer.

Tags: , ,

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List

bedava tv izle