.Net Framework übergreifend entwickeln mit Portable Class Libraries

Mittlerweile gibt es neben dem .Net Framework 4 auch Silverlight, Windows Phone 7 und Xbox 360. Obwohl man überall in C# entwickeln kann stösst man doch schnell einmal an eine Grenze: Eine Klassenbibliothek vom vollen .Net Framework kann nicht in einem Silverlight-Projekt verwendet werden. Gleiches gilt für Windows Phone 7. Und um es noch ein wenig mühsamer zu machen sind Silverlight und Windows Phone 7 auch nicht kompatibel.

Dies zeigt sich mit dieser Fehlermeldung wenn man versucht eine *.dll einzubinden:

 

Portable Library Tools als Lösung

Eine Entdeckung der Tech Conference war für mich die Portable Class Libraries. Dieser Projekt-Typ ist vergleichbar mit einer gewöhnlichen Class Library. Allerdings kann man mehrere Framework-Plattformen als Ziel wählen.

Die einzelnen Frameworks haben eine grosse Menge an Funktionen die überall zur Verfügung stehen. So lange man in diesem Bereich bleibt ist dieser Projekttyp eine sehr gute Lösung um den Code nur einmal zu schreiben. Was genau geht und wo die Grenzen liegen ist in der MSDN gut beschrieben.

Benötigt man die Framework-Spezifischen Teile kann man immer noch mehrere Projekte machen und die *.cs Dateien verlinken.

 

Installation

Wie immer mehr Bibliotheken und Erweiterungen kann man die Erweiterung Portable Library Tools über NuGet installieren. Sobald dies gemacht ist gibt es eine neue Projektvorlage:

Über die Projekteigenschaften kann man die Zielframeworks sehr einfach auswählen:

Der wiederverwendbare Code kann nun in diesem Projekt entwickelt werden und steht Anwendungen der aktivierten Frameworks zur Verfügung.

 

Ausblick

Windows 8 wird mit Metro noch ein weiteres Framework in die .Net Welt bringen. Gemäss den Informationen aus der Tech Conference von Mitte März in Baden gibt es aber eine gute Nachricht: Visual Studio 11 (oder wie man die Version am Ende nennt) wird diesen Projekttyp bereits integriert haben. Eine Nachinstallation wird so nicht nötig sein und damit auch den Anwendern der Express-Edition zur Verfügung stehen.

 

Advertisements

Kurz-Tipp: IIS Express in Visual Studio verwenden

Wer mit Visual Studio eine Webanwendung entwickelt wird häufig den eingebauten Webserver Cassini nutzen. Dieser funktioniert für die meisten Anwendungen ohne Probleme. Will man aber schon zur Entwicklungszeit einige IIS-spezifische Funktionen verwenden, stösst man damit schnell an die Grenzen. IIS Express ist in solchen Fällen eine gute und einfach zu konfigurierende Alternative zum ausgewachsenen IIS.

 

IIS Express installieren

Der einfachste Weg zur Installation von IIS Express führt über den Web Platform Installer. Mit diesem Tool kann man über eine einfache Maske diverse Web-Pakete (von PHP bis WordPress) mit einem Klick installieren. Als Alternative kann man den direkten Link aufrufen der einem gleich den IIS Express auswählt.

 

In Visual Studio nutzen

Um IIS Express zu nutzen muss man den Einstellungsdialog des gewünschten Webprojektes öffnen. Im Reiter Web kann man unter Servers den IIS Express auswählen. Die Projekt-URL kann einen beliebigen Zusatz haben oder nur aus localhost und einem Port bestehen.

Wichtig: Nach dem man die gewünschte URL eingegeben hat muss man das virtuelle Verzeichnis anlegen.

Startet man das Webprojekt nun mit F5 wird IIS Express verwendet. Will man doch wieder Cassini nutzen wählt man einfach auf der gleichen Maske den Development Server aus.

 

Fazit

IIS Express ist sehr schnell konfiguriert und man kann problemlos jederzeit wieder zurück zu Cassini. Wer mit Cassini Probleme hat (zum Beispiel wenn die Webanwendung immer wieder abstürzt) kann so in kurzer Zeit auf IIS Express wechseln und überprüfen ob das Problem vom Webserver abhängt oder doch selber verursacht wurde.

Abhängigkeiten auflösen mit NuGet

Wer kennt es nicht: Um mal schnell etwas in Visual Studio zu testen benötigt man erst die eine Library und dann noch eine und noch eine. Am Ende hat man die erste Stunde lang nur versucht die Abhängigkeiten so aufzulösen, das auch noch alle Versionen miteinander arbeiten. Wie schön wäre es doch wenn man einfach sagen könnte ich will Library XY und alle Abhängigkeiten werden einem automatisch aufgelöst?

Genau dies ist die Aufgabe von NuGet. Mit nicht einmal 500kb ist diese Visual Studio Erweiterung sehr klein und schnell heruntergeladen. Nach der Installation gibt es unter Tools einen Eintrag „Library Package Manager“, über den man NuGet verwalten oder die PowerShell-Konsole aufrufen kann. Falls weder der Eintrag unter Tools noch das Kontextmenü erscheint hilft ein Neustart von Visual Studio.

Ich persönlich bevorzuge für solche Tätigkeiten eine grafische Oberfläche. Um die aufzurufen genügt ein Rechtsklick auf den References-Ordner. Das dazugehörige Kontextmenü wurde durch NuGet um den Punkt „Add Library Package Reference…“ erweitert.

Die grafische Oberfläche bietet einem einen praktischen Suchdialog an. Hat man das gewünschte gefunden, kann man mit einem Klick auf den „Install“ Knopf die Library für das ausgewählte Projekt installieren. Allfällige Abhängigkeiten werden dabei im gleichen Durchgang aufgelöst und ebenfalls installiert.

Wer mehr zu NuGet erfahren will findet alles nötige auf http://nuget.codeplex.com/.

LINQ: eine Liste anhand einer anderen Liste sortieren

Ich hatte vor kurzem eine „kleine“ Herausforderung zu lösen: Als Input hatte ich eine Liste A mit Primärschlüsseln und ich sollte eine Liste B mit den dazugehörigen Objekten zurückliefern – aber in der gleichen für mich nicht nachvollziehbaren Reihenfolge wie ihre Id in Liste A erscheinen.

Die Aufgabe wäre nicht der Rede wert wenn man nach einem bestimmten Feld sortieren könnte. In dem Fall gäbe es genügend Möglichkeiten um ein Order By in LINQ oder schon in SQL durchzuführen.

 
Ein JOIN als Lösung
Auf Stackoverflow fand ich eine Antwort von Simon D die mir den Weg zeigte. Ein einfacher JOIN in LINQ löst das Problem auf eine sehr elegante Weise:

var orderedByIDList = from i in ids 
                       join o in objectsWithIDs
                       on i equals o.ID
                       select o;

 
Ein Beispiel
Um die Lösung in Aktion zu sehen habe ich diesen kleinen Code-Schnipsel zusammengestellt. Eine Liste von Personen soll nach ihren Id’s sortiert werden, so wie sie in der Liste filter festgelegt wurden. Um Daten nicht aus einer DB holen zu müssen dient die Methode GetSampleData() als Datengenerator.

void Main()
{
        List<long> filter = new List<long>(){1,3,2};
        List<Person> result = Person.GetSampleData();
        result.Dump();
        
        var orderedResult = from f in filter join r in result on f equals r.Id select r;
        orderedResult.Dump();        
}

public class Person 
{
        public long Id;
        public string LastName;
        public string FirstName;
        
        public static List<Person> GetSampleData()
        {
                List<Person> data = new List<Person>(){
                        new Person(){Id = 1, LastName = "Vettel", FirstName = "Sebastian"},
                        new Person(){Id = 2, LastName = "Massa", FirstName = "Felipe"},
                        new Person(){Id = 3, LastName = "Hamilton", FirstName = "Lewis"},
                };
                
                return data;
        }
}

Gibt man dieses Beispiel in LINQPad als „C# Program“ (bei Language) ein, wird die Liste bei der 2. Ausgabe entsprechend verändert:

 
Fazit
Man sollte auch kleine Probleme nutzen um sein Wissen auszubauen. LINQ bietet einem die Möglichkeit erstaunliche Ansätze zu einer Lösung zu kombinieren und Probleme aus einem ganz anderen Blickwinkel anzugehen. Und Stackoverflow ist ein idealer Anlaufort für solche Probleme.

Silverlight 4 Hands-On Lab

Am 15. Januar besuchte ich das Hands-On Lab zu Silverlight 4 bei Microsoft in Wallisellen. Bisher habe ich nur ein wenig mit den Beispielen zu Silverlight experimentiert. Hier mal ein wenig mit den Komponenten gespielt, da ein wenig Code angepasst. Meine Erfahrungen mit Silverlight waren somit bisher vor allem theoretischer Art. Das Hands-On Lab war daher eine gute Gelegenheit, endlich mehr zu machen als nur ein wenig zu Spielen.

 
Was ist ein Hands-On Lab?
Bei einem Hands-On Lab nimmt man sein eigenes Laptop mit und kann selber die vorgegebenen Beispiele ausführen. Beim Lab zu Silverlight war die Einführung sehr kurz, dafür die Aufgabe umso grösser. Auf 104 Seiten wurde ausführlich beschrieben, wie man eine Silverlight Applikation mit WCF RIA Services baut. Die Applikation nutzt die Nordwind Demo-DB und zeigt die Bestellungen an. Ein Sub-Report ermöglicht die Bearbeitung von Details der ausgewählten Bestellung. Neben dieser Grundfunktionalität gibt es einige kleine Helfer wie die Validierung der Eingabe, einen Busy Indikator beim Laden der Daten, eine Autocomplete-Box für die Suche nach Städten und die Druckfunktion.

Kurzum: Die Applikation des Hands-On Lab ermöglicht einem komprimiert und in sich stimmig die wohl am häufigsten benötigte Funktionalität auszuprobieren.

 
Derzeit noch alles Beta
Sowohl Silverlight 4 wie auch Visual Studio 2010 sind erst in Betaversionen erhältlich. Die finalen Versionen sollten wohl in 3-6 Monaten erscheinen. Mich erstaunte die Geschwindigkeit von Visual Studio. Von 2008 ist man sich einen langsamen Start gewöhnt. 2010 dagegen startet sehr schnell.
In der Beta muss man noch bei fast jeder Aktion im Server-Teil ein rebuild all durchführen. Das lässt sich zwar einfach von Hand machen, doch wenn man dies vergisst, bekommt man nur noch Fehlermeldungen zu Gesicht. Ein automatisches nachziehen der generierten Proxy-Klassen wird die Entwicklung nochmals deutlich angenehmer machen. Zudem stürzt Visual Studio 2010 in der Beta 2 zu häufig ab. 1 Absturz pro 45 Minuten ist auch bei dem schnellen Start einfach noch zu viel. Für eine Beta-Version ist der Gesamteindruck aber schon sehr gut.

 
Fazit
Ich fand das Lab eine gute Erfahrung. Man kann selber im eigenen Tempo arbeiten und stösst man auf Probleme, hat man sehr kompetente Personen im Raum, die einem helfen können. Bei Silverlight gefiel mir wie einfach und vor allem schnell man ein Grid anzeigen konnte. Kein herumschlagen mit Requests, Postbacks oder Session – einfach nur hineinziehen, verbinden und es lief.

Auch die einfache Verwendung von RIA Services hat mich positiv erstaunt. Die Objekte werden zum DB-Schema passend angelegt und man kann damit loslegen. Kein Aufbau von Sessions und keine Proxy-Errors. Werden die Daten im Subreport geändert, wird erst validiert und dann gespeichert. Hat man es dann gespeichert, bleibt es dies auch. Und vor allem wird nicht schon gespeichert, wenn der Benutzer nur etwas im Formular ändert. Somit fällt auch viel von dem Overhead weg, der mich derzeit bei der WebForms-Entwicklung stört.

Silverlight ist definitiv eine sehr interessante Technologie. Und mit Version 4 gibt es einen grossen Schritt nach vorne.

Code formatieren in Eclipse und Visual Studio

Beim editieren von Source Code kommt die Formatierung schnell durcheinander. Man hat natürlich die Möglichkeit die von Hand wieder herzustellen. Allerdings ist das mühsam und man verschiebt es auf später. Nach weiteren Änderungen und noch mehr Vorsätzen für später hat man dann etwas, was man erst recht nicht mehr anpassen will.

Dies alles kann man sich ersparen, wenn man die in der IDE eingebauten Funktionen nutzt.

 
Eclipse
In Eclipse kann man den Code mit [Ctrl]-[Shift]-[F] sauber formatieren oder mit [Ctrl]-[I] nur die Einrückung korrigieren. Als Grundlage für die Formatierung dient die in den Einstellungen gewählte Formatierungsvorlage. IBM hat dazu eine ausführliche Erklärung.

 
Visual Studio
In Visual Studio gibt es eine vergleichbare Funktion. Mit [Ctrl]-[K] [Ctrl]-[D] wird der Code neu formatiert. Die Formatierung kann auch hier eingestellt werden. Auf MSDN gibt es dazu einen passenden Abschnitt.

 
Eine kleine Funktion die einem viel Ärger ersparen kann. Wenn man die Einstellungen verändert, sollte man diese Exportieren und ebenfalls in die Versionsverwaltung aufnehmen. Bei der Arbeit im Team sollte man nur an einem Ort die Einstellungen verändern. Ansonsten läuft das sehr schnell auseinander. Und wenn nur einer die Änderungen für alle macht spart man erst noch Zeit.

Leichter debuggen mit DebuggerDisplay

Der Debugger von VisualStudio zeigt einem einen Tooltip an, sobald man mit der Maus über eine Variable oder eine Klasse fährt. Je nach dem ist dieser Text mehr oder weniger hilfreich. Man hat zwar immer die Möglichkeit, die einzelnen Felder und verschachtelten Werte durchzuklicken, bis man die gewünschten Werte angezeigt bekommt. Je grösser die Klasse und je mehr Felder diese beinhaltet, desto unübersichtlicher und mühsamer wird es.

Als kleines Beispiel dient mir eine Klasse Person. Dieses repräsentiert einen Menschen und der Vor- und Nachname sind die Informationen, über die ich das Objekt zuordnen kann. Beim debuggen wäre es für mich hilfreich, genau diese Informationen im Tooltip angezeigt zu bekommen (und eine Id, sollten mehrere Personen den gleichen Namen haben). Eine ganz einfache Personenklasse kann so aussehen:

using System;

namespace DebuggerInfo
{
    class PersonBasic
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public int Id { get; set; }

        public PersonBasic(String firstName, String lastName, int id)
        {
            FirstName = firstName;
            LastName = lastName;
            Id = id;
        }
    }
}

Als Tooltip wird nur der Namespace und Klassenname gezeigt:

Tooltip mit Klassennamen

Wie kann ich nun eine bessere Beschreibung bekommen?

 
Option 1: ToString() überschreiben

Die einfachste Möglichkeit um die gewünschte Anzeige zu erhalten ist das überschreiben der ToString-Methode. Dazu genügt dieses kleine zusätzliche Stück Code:

public override string ToString()
{
    return String.Format("{0} {1} {2}", FirstName, LastName, Id);
}

Der Debugger nutzt nun die ToString-Methode und liefert mir eine hilfreiche Anzeige zurück:
Tooltip mit ToString

 
Option 2: Attribut DebuggerDisplay

Ist die ToString-Methode schon überschrieben und liefert nicht die gewünschten Informationen, kann mit dem Attribut DebuggerDisplay auf Ebene der Klasse die Anzeige im Debugger geändert werden. Dies befindet sich im Namespace System.Diagnostics. Der dazugehörende Code sieht so aus:

namespace DebuggerInfo
{
    [DebuggerDisplay("Person: {LastName} {FirstName}")]
    class PersonDebug
    {
        // Klassendefinition
    }
}

Im Debugger gibt es das gewünschte Ergebnis:

Tooltip mit DebuggDisplay

 

Fazit:
DebuggerDisplay kann einem helfen, gewünschte Informationen nur für den Debugger aufzubereiten. Eine sinnvolle ToString-Methode sollte aber zu erst erstellt werden.