Entries Comments



Nyheder for uge 20, 2008

17 May, 2008 (15:00) | Nyheder | By: Kim Harding

  • Visual Studio 2008 Service Pack 1 Beta er nu ude. At kalde den en service pack, er nok at gradebøje begrebet, da det mere minder om en ny release end en service pack. SP1 indeholder bl.a. ADO.NET Entity Framework, LINQ to Entities, ADO.NET Data Services (Astoria) og SQL 2008 support. Desuden er der en lang række forbedringer til de eksisterende teknologier. Den endelige version af SP1 forventes frigivet senere på sommeren. SP1 Beta virker ikke sammen med Silverlight 2.0 Beta.
  • Enterprise Library 4.0 er frigivet. De største ændringer er tilføjelsen af Unity Application Block, som er en dependency injection container. Desuden har alle blocks fået tilføjet flere performance counters, så det bliver nemmere at monitorere ens applikationer baseret på Enterprise Library.
  • Virtual PC 2007 Service Pack 1 er frigivet og kan nu køre på: Windows Viste Ultimate SP1, Windows Vista Business SP1, Windows Vista Enterprise SP1 og Windows XP Prof SP3.
  • Firefox 3 RC1

Egne metoder på ASP.NET MVC Html Helper

16 May, 2008 (10:51) | ASP.NET MVC | By: Kim Harding

Jeg arbejder i øjeblikket på en web-app som implementeres i ASP.NET MVC. Jeg har bl.a. brug for at generere en navigator som ser sådan her ud:

image

I HTML ser det sådan her ud:

<a class="activenavitab" href="/">Start</a><span class="hide"> | </span>
<a class="navitab" href="/news">Nyheder</a><span class="hide"> | </span>
<a class="navitab" href="/articles">Artikler</a><span class="hide"> | </span>
<a class="navitab" href="/videos">Video</a><span class="hide"> | </span>
<a class="navitab" href="/about">Om os</a><span class="hide"> | </span>
<a class="navitab" href="/contact">Kontakt</a><span class="hide"> | </span>

Navigatoren sidder på en masterpage og der skal derfor genereres HTML efter hvilken side, der er den aktive. CSS klassen på <a> skal være enten "activenavitab" eller "navitab" alt efter den aktive side.

Første bud på en implementation kunne være:

namespace KimHarding.CS.Web {
    public class NavigatorTab
    {
        public String Title;
        public String Url;
        public int Id;
    }

    public static class HtmlHelper {

        public static String Navigator(int selectedTabId, IEnumerable<NavigatorTab> tabs)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var tab in tabs)
            {
                sb.AppendFormat(
                    "<a class=\"{0}\" href=\"{1}\">{2}</a><span class=\"hide\"> | </span>" , 
                    selectedTabId == tab.Id ? "activenavitab" : "navitab",
                    tab.Url,
                    tab.Title);
            }
            return sb.ToString();
        }
    }
}

I vores view vil vi kunne generere en navigator ved

<%= HtmlHelper.Navigator(selectedTabIndex, myTabs) %>

ASP.NET MVC ViewPage og HtmlHelper

I ASP.NET MVC er et view en subklasse af ViewPage og man bruger ikke kontroller til at generere HTML. Istedet har man i sit view adgang til et Html object som indeholder en række metoder til at generere HTML.

image

For at oprette et hyperlink kan man f.eks. gøre følgende i sit view:

<%= Html.ActionLink("Opret ny artikel", "New", "Articles") %>

og man vil få genereret:

<a href="/Articles/New">Opret ny artikel</a>

Egne metoder på HtmlHelper

I stedet for at lave sine egne utility-klasser med HTML genereringsmetoder, kan vi bruge extension-metoder til at sætte vores egne metoder ind på HtmlHelper.  Så vi i stedet for

<%= HtmlHelper.Navigator(selectedTabIndex, myTabs) %>

kan skrive

<%= Html.Navigator(selectedTabIndex, myTabs) %>

En let refactoring af vores kode giver den ønskede effekt:

namespace KimHarding.CS.Web {
    public class NavigatorTab
    {
        public String Title;
        public String Url;
        public int Id;
    }

    public static class HtmlHelperExtensions {

        public static String Navigator(
            this HtmlHelper htmlHelper,
            int selectedTabId,
            IEnumerable<NavigatorTab> tabs)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var tab in tabs)
            {
                sb.AppendFormat(
                    "<a class=\"{0}\" href=\"{1}\">{2}</a><span class=\"hide\"> | </span>" , 
                    selectedTabId == tab.Id ? "activenavitab" : "navitab",
                    tab.Url,
                    tab.Title);
            }
            return sb.ToString();
        }
    }
}

For at få ASP.NET til at "loade" vores extension-metoder ind i rette scope skal der lige laves en tilføjelse til Web.config.

image

Partielle metoder i C# 3.0

19 December, 2007 (10:03) | C# | By: Kim Harding

En af de mindre kendte nyheder i C# 3.0 er partielle metoder. Partielle metoder er tænkt til at implementere letvægt events (callbacks) i forbindelse med kodegenerering. Designeren i LINQ to SQL er et af produkterne i Visual Studio 2008, som gør brug af kodegenerering og partielle metoder.

Så lad os lave en simpel LINQ to SQL model, som indeholder en Blog klasse med Id og Title properties.

image

LINQ to SQL genererer nu filen Blog.designer.cs som bl.a. indeholder vores Blog klasse.

public partial class Blog : INotifyPropertyChanging, INotifyPropertyChanged {
        private int _Id;
        private string _Title;

    #region Extensibility Method Definitions
      partial void OnLoaded();
      partial void OnValidate(System.Data.Linq.ChangeAction action);
      partial void OnCreated();
      partial void OnIdChanging(int value);
      partial void OnIdChanged();
      partial void OnTitleChanging(string value);
      partial void OnTitleChanged();
    #endregion

        public Blog()
        {
            OnCreated();
        }

        [Column(Storage=”_Title”, CanBeNull=false)]
        public string Title
        {
            get
            {
                return this._Title;
            }
            set
            {
                if ((this._Title != value))
                {
                    this.OnTitleChanging(value);
                    this.SendPropertyChanging();
                    this._Title = value;
                    this.SendPropertyChanged(”Title”);
                    this.OnTitleChanged();
                }
            }
        }

         [Column(Storage=”_Id”, AutoSync=AutoSync.OnInsert, IsPrimaryKey=true)]
        public int Id
        {
           …
        }

        public event PropertyChangingEventHandler PropertyChanging;
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void SendPropertyChanging()
        {
            …       
        }
        protected virtual void SendPropertyChanged(String propertyName)
        {
            …       
        }
    }

Blog klassen har en region med partielle metoder (OnLoaded, OnCreated …) som bliver kaldt de steder i koden, hvor der ændres tilstand. F.eks. vil konstruktøren kalde den partielle metode OnCreated.

       public Blog()
        {
            OnCreated();
        }

Hvis vi bare bruger klassen uden selv at lave tilføjelser vil kompileren fjerne alle kald af partielle metoder. F.eks. vil konstruktøren reduceres til:

        public Blog()
        {
        }

Hvilket jo er fornuftig, da vi ikke har defineren en krop til OnCreated metoden. Hvis vi er interesseret i at reagere på den hændelse som den partielle metode udtrykker, så må vi lave en partiel klasse udvidelse og definere metoden. F.eks.

      public partial class Blog
      {
          partial void OnCreated()
         {
             Console.WriteLine(”Ny blog instans…”);
         }
     }

Der gælder flg. regler ved brug af partielle metoder:

  • Partielle metoder kan ikke have en access-specifier. Partielle metoder er implicit erklæret som privat
  • Retur-typen skal være void
  • Supporterer ikke out parameter (ref og params er OK)
  • Man kan ikke binde en delegate til en partiel metode med mindre den er defineret med krop

På et senere tidspunkt vil jeg skrive lidt mere om brug af partielle metoder og sammenligne dem med template method mønsteret fra GoF Design Pattern bogen.

Slides til "En dag med LINQ"

18 December, 2007 (21:20) | C#, Foredrag, LINQ | By: Kim Harding

Tak til alle som mødte op til "En dag med LINQ" foredragene i Århus og København!

Hvis du er interesseret i slides og eksempler kan du hente dem her.

Mange af eksemplerne er skrevet som unit tests. Som jeg nævnte på foredraget, så bruger jeg det nye xUnit.net test-framework. xUnit.net er lavet at James Newkirk, der også er ophavsmand til NUnit. xUnit.net kan integreres i Visual Studio vha. TestDriven.net.

Jeg har ikke inkluderet koden til det Domain Driven Design framework jeg benyttede i "VideoStore" eksemplet i den sidste session. Når frameworket er blevet mere modent vil jeg sandsynligvis gøre det til open-source. Hvis jeg kan kontrollere mit risalamande indtag i juledagene, så vil jeg skrive lidt på blog’en om de ideer og tricks, der ligger bag.

En dag med LINQ

14 November, 2007 (21:15) | Foredrag | By: Kim Harding

René Løhde fra Microsoft har givet mig muligheden for at tale en hel dag om LINQ. Det er jo svært at sige nej til, når man mener at LINQ er det eneste interessante, der er sket i vores fag de seneste 15 år!

Vi forventer stor interesse, så derfor stiller jeg op både øst og vest for Storebælt. Nærmere bestemt den 11. december i Århus og den 13. december i København.

Interviewet af Version2

25 September, 2007 (20:05) | Interview | By: Kim Harding

Tania Andersen fra Version2 fangede mig på telefonen til en snak om hvad der rør sig i øjeblikket. Det er der blevet et par artikler ud af:

JAOO 2007

21 September, 2007 (20:27) | Foredrag | By: Kim Harding

Det er ved at blive efterår og det betyder også at JAOO konferencen står for døren. I år har jeg stået for planlægningen af følgende spor:

Jimmy Nilsson og jeg har en session på LINQ sporet med titlen “LINQ for Domain Driven Design”, hvor vi sætter LINQ (specielt LINQ to SQL) i kontekst af Domain Driven Design og undersøger hvordan LINQ påvirker vores løsninger.