Apr 212011
 

Wie kürzlich erst gesagt gibt’s etliche Möglichkeiten, das INPC zu handhaben. Ich habe jetzt einen neuen Favoriten:
T4 Code Snippets

Vorteile: Der Code muss nicht manuell geschrieben werden, kann auch zentral refactored werden, ist aber schon zur Compilezeit vorhanden und auch sichtbar. UND: die Properties inkl. Boilerplate-Code landen in einem eigenen CodeFile und verwässern nicht den Teil, wo die komplexeren Sachen passieren.
Ach ja, und noch einer: Die Snippets liegen im Projekt, damit auch im CVS und sind immer für das ganze Team sichtbar und verfügbar, auch bei abweichender IDE-Config.

Nachteil: Evtl. minimal längere Compilezeit, spezielle Templates, z.,b. um die Zusatzfeatures des NotifyPropertyWeaver nachzubilden muss man erst noch erstellen.

Außerdem sehr schick: die verkürzte Grid!Syntax für Row-/ColumnDefinition.

Und für die T4-Snippets gibt es sicher noch weitere gute Anwendungen. Z.B. Standardvalidierung mit IDataErrorInfo, Pflichtfelder, Min/Max-Grenzen etc.

Apr 152011
 

WPF-DataBinding rocks! Schön ist auch, dass es sowohl mit den (relativ neuen) DependencyProperties als auch mit den guten alten CLR-Properties (POCOs = Plain old CLR-Objects) gut harmoniert, wenn man denn INotifyPropertyChanged aus dem ComponentModel implementiert.
Das ist auch nicht schwierig, sorgt aber immer wieder für Diskussionen, wenn es darum geht, wie man am besten MagicStrings (PropertyNamen) vermeidet, blöde Copy/Paste-Fehler verhindert (z.B. BackupFieldName statt PropertyName in den EventArgs), ob man Reflection einsetzt (Expressions statt MagicString, Performance-Hit?) usw.
Eine Muster-Implementierung, aber was noch viel wertvoller ist, eine Diskussion verschiedener Ansätze findet sich im OpenSource-Project CompositeExtensions.

Vermutlich jedes GUI-Framework  bietet mindestens einen Lösungsansatz dafür.
Heute habe ich noch einen weiteren gefunden: den NotifyPropertyWeaver.

Das Konzept ist nicht so überraschend:
Die Properties werfen keinerlei Events mehr im explizit geschriebenen (Boilerplate-)Code. Stattdessen tragen sie eine recht kompakte Konfiguration an Klassen und Properties, z.B. AOP-like über Attributes.
Diese muss man natürlich später von irgendwem noch in Code umgewandelt werden, und genau dafür gibt es dann auch wieder zahlreiche Ansätze:

  • Ein DynamicProxy könnte Property-Aufrufe abfangen und z.B. zusätzliche Aufrufe hinzufügen, Events auslösen etc. (Sehr stylischer Artikel dazu)
  • Basisklassen können die Konfiguration umsetzen. Das hat natürlich den großen Nachteil, dass man von dieser Klasse ableiten muss und keine andere Basisklasse verwenden kann.
  • Der PropertyWeaver setzt auf einen Post-Compile-Task: Nachdem der eigentliche Code (Properties werfen keine Events) kompiliert ist, bearbeitet der PropertyWeaver die generierte (IL-)Assembly nach und ergänzt sie um die Event-Aufrufe etc. Dabei sind auch komplexere Situationen möglich, wie z.B. abhängie Properties, für die auch dann ein Event geworfen werden muss, wenn sich der Wert einer bestimmten anderen Property ändert.

    Vorteil: Der generierte Code sieht quasi genau so aus wie handgeschriebener Boilerplate-Code, und ist damit auch zur Laufzeit gleichwertig. Hilfsmittel wie Reflection werden zur Laufzeit nicht benötigt, die statisch vorhandere Information wird in statischen Code umgewandelt, feine Sache. Die Nachteile des tatsächlich manuell fabrizierten Codes, nämlich die ständigen Fehlerquellen Typo und Copy/Paste sind quasi eliminiert, da der Code ja maschinell erzeugt wird. Ok, ein Restrisiko bleibt durch fehlerhafte Konfiguration, aber ein Bisschen muss man halt schon sagen was man will, wenn man’s auch kriegen möchte (Garbage In, Garbage Out).

    Leider gibt’s bei aller Eleganz dieser Lösung auch Nachteile – There ain’t no free lunch:
    Der Code wird erst Post-Compile ergänzt, er landet also nicht im Code-File in der IDE sondern nur in der erzeugten dll. Somit ist er dann auch nicht zugänglich für z.B. statische Code-Analyse (Resharper, StyleCop, etc.), und beim „Lesen“ des Codes muss man immer beachten, dass evtl. noch mehr passiert als dort steht.
    Glücklicherweise werden die zugehörigen pdb-Files ebenfalls ergänzt, Debugging funktioniert also trotzdem. Und Unit-Tests durchlaufen natürlich auch den endgültigen Code, der Post-Compile-ergänzte Teil wird also mitgetestet.

    Feb 232011
     

    Heute schon die int.MaxValue-Grenze übertreten? Für fast jeden kommt der Moment irgendwann, an dem int = Int32 nicht mehr ausreicht und auch ein Unsigned Int 64 knapp werden könnte. Klassische Beispiele: ewig hochgezählte Unique-IDs oder Comparer, die Strings numerisch sortieren sollen. Normalerweise kein Problem, aber es ist schwer zu garantieren, dass die Grenzen tatsächlich eingehalten […]

    Dez 082010
     

    …vielleicht eher für’s nächste Jahr interessant, obwohl der Advent ja noch ein paar Türchen bereithält: Ich habe eine kleine Adventskalender-Anwendung gebaut, die ich mit Fotos von meinem Kleinen an dessen Großeltern verteilt habe. Was man davon abgreifen kann? Beispielanwendung mit MVVM (MVVM-Lite Toolkit) – Aber Achtung, an 2-3 Stellen hab ich durchaus mal die Quick’n’Dirty-Lösung […]

    Aug 312010
     

    Bei meinen ersten Gehversuchen mit dem Entity Framework bin ich natürlich gleich über die erste Hürde gestolpert: Da ich weder mit Kanonen auf Spatzen schießen wollte, noch externe Libs=Fehlerquellen einbinden wollte, startete ich mit dem MS SQL Server in der Compact Edition. Soweit so gut, dank EF gelang die DB-Erstellung recht mühelos direkt aus VS2010 […]

    Jun 132010
     

    Einige echt nützliche Features für VisualStudio können mit diesen AddIns (von Microsoft selbst veröffentlicht) nachgerüstet werden: PowerCommands for VisualStudio 2010 (gabs auch schon für 2008: PowerCommands for Visual Studio 2008) Visual Studio 2010 Pro Power Tools Eine Liste mit noch viel mehr Productivity-Steigerungen kann man z.B. bei Scott Hanselman lesen.

     Posted by at 00:28
    Jun 122010
     
    Continuous Integration (CI) mit TeamCity, NAnt und SVN

    Jeder Entwickler kennt sicherlich das Problem, dass seine eigenen Tests häufig nicht aussagekräftig genug sind. Der 100% identische Programmcode kompiliert bei Entwickler A, nicht aber bei Entwickler B („wirklich 100% gleich?“ „Ja, klar.“ „Auch Komponente X“ „Sicher“ „Und du hast die selbe Version von Lib Y?“ „Uhoh…“). Noch schlimmer: Bei beiden kompiliert der Code, aber […]

     Posted by at 21:21