Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Category .NET

In dieser Kategorie geht es um das Microsoft .NET Framework und damit zusammenhängende Technologien wie CLR, C#, ASP.NET, WCF, WF und WPF.

Tuesday, 31. January 2012


Why do we need partial application? – Part 2 of n – Simulating type classes in C# and F#

Filed under: C#,F# — Steffen Forkmann at 16:48 Uhr

This is yet another blog post in my Currying and Partial application series. This is what I have posted so far:

In this post I want to show you a way to simulate type classes in C# and F#. Type classes are this wonderful feature in Haskell which allow you to specify constraints on your polymorphic types. We don’t have this in C# nor F#.

Let’s start with the following problem: We want to compute the sum of the squares of arbitrary numbers. We want to write something like this:

image

The problem is we don’t have a generic * function and of course we’d also need a generic + operator and maybe a generic zero. Obviously we need a constraint on the generic parameter T since + might not be defined for any type. So let’s define an interface for numbers:

Nothing special here, so let’s get straight to the implementation for integers and doubles:

So far so good. With this in our pocket we rewrite SumOfSquares() into this:

The trick is that we pass the concrete implementation as the first parameter into our function. This works exactly like a type constraint or as Simon Peyton-Jones would say: the vtable travels into the function. Notice that we don’t have access to the definition of in nor double. There is no way for us to express that int or double implement a number interface.

Now let’s try this out:

As you can see, this is perfectly type safe. We now have a way for poor man’s type classes in C#. Yay!

Now what has this to do with partial application? Let’s look at the same thing in F#:

We’re using a lot of partial application here. Exercise: Try to spot all the places.

Ok, you’re right. This post might be a little bit far away from the partial application stuff, but it’s still related. Somehow.

Tags: , , , ,

Monday, 30. January 2012


Currying and uncurrying in C# and F#

Filed under: C#,F# — Steffen Forkmann at 17:00 Uhr

In the last couple of days I started to write some posts about Currying and Partial application:

This time I want to show you how we can write a higher-order function which allows us to curry another function. Remember the multiplication function from the first post and it’s curried form:

Currying

The question is: how can we automate this transformation process? Remember we want to have the curryied form for partial application:

Let’s look at the signature of the desired Curry-function: in our case it has to take Func<int, int, int> and returns Func<int, Func<int, int>>.

If we generalize the ints to generic parameters and fix the signature then the implementation is trivial (Compiler Driven Programming). There is exactly one way to make this work:

The F# implementation does exactly the same, but without all the annoying the type hints:

Uncurrying

Of course you can undo the currying by applying a generic Uncurry-function:

And in F# this looks like this:

Libraries

Currying and Uncurrying are two very important concepts in functional programming so they are included in a couple of libraries:

  • You can find it at the top of the Prelude in FSharpx (read more).
  • You can find it in the Haskell Prelude.
  • You can find similar functions in Scalaz.
  • Adrian Lang wrote a library called partial-js which allows to do something similar in JavaScript.
Tags: , , ,

Sunday, 29. January 2012


Why do we need partial application? – Part 1 of n – Fluent interfaces and piping

Filed under: C#,F# — Steffen Forkmann at 10:34 Uhr

My last blog post was yet another introduction to Currying and Partial application. Now I want to put the focus more on the why part. Why do we want to have our functions in curryied form most of the time? This is the first part of a small blog post series and shows partial application in F# pipelines.

Using “Fluent interfaces” is a popular technique to write code in a more readable form. In languages like C# they also provide a way to create the code much faster. On every . we get IntelliSense and this gives us a “fluid” way of writing.

Let’s consider the following task: we want to compute the sum of the square roots of all odd numbers between 1 and 100. In C# we can use the LINQ method chaining approach in order to do something like this:

image

Now how does this look in F#? It’s basically the same. We replace every . with the |> operator and use the analogous Seq.* functions:

image

Oups! What happened here? The F# compiler noticed a type error. Math.Sqrt needs a float as input but we gave it an int. C# uses implicit casts between int and float so we didn’t noticed the problem there. Implicit casts are a little bit problematic, at least if you want to have proper type inference so F# doesn’t have this feature. No problem, we are programmers so let’s add the conversion manually:

Notice that float is a function from int to float and not a cast.

Now you might ask: how does this all relate to partial application? The answer is simple: In every pipeline step we use a higher-order function (Seq.*) and apply the first parameter with a lambda. The second parameter is given via the |> operator from the line above.

image

By applying our rule of thumb from the last post were are able to remove the x parameters:

Now let’s step back to C#. Keeping this knowledge in mind we try to apply the same rule in order to get rid of the x parameters:

image

Oups again! Now we see same error in C#. In this case it doesn’t know how to apply the implicit cast. As I said they are “problematic”, but we know how to fix this:

Tags: , ,

Sunday, 20. June 2010


CodingDojo in TDD – Die einfachste Lösung siegt

Filed under: C#,Coding Dojo,Kata — Steffen Forkmann at 18:27 Uhr

Auf dem .NET OpenSpace Süd in Karlsruhe hatte ich heute die Gelegenheit bei einem Coding Dojo mit Ilker Cetinkaya mitzumachen. Leider ist das Dojo nicht so richtig in Fahrt gekommen und wir haben es praktisch nicht geschafft auch nur eine einzige Regel der Kata.RomanNumerals zu implementieren. Der Grund dafür war (sicherlich nicht nur) aus meiner Sicht, dass es zwei starke Fraktionen innerhalb des Teams gab. Auf der einen Seite “Coder”, die sich tatsächlich von den Tests treiben lassen wollten und auf der anderen Seite eine Gruppe der “Knobler”, die sich nicht mit dem Test-first-Ansatz identifizieren können und lieber am Board einen Algorithmus entwickeln.

Aus meiner Sicht sind beide Ansätze für sich betrachtet auch völlig in Ordnung und können zu sehr guten Lösungen führen.

Wer z.B. nicht glaubt, dass der strikte Test-first-Ansatz für Kata.RomanNumerals funktioniert, der kann gern die Teilnehmer vom 2.ten Hamburger Coding Dojo fragen oder das github-Repository dazu durch browsen und die Entwicklung der Commits verfolgen.

Was aber offensichtlich überhaupt nicht funktioniert ist der Mittelweg. Wenn sich beide Gruppen nicht auf das Vorgehen einigen und im Zweifel immer nur der “lauteste” Änderungsvorschlag gewinnt, dann wird das Ergebnis mitunter unbefriedigend für beide Seiten. Beim Karlsruher-Dojo hatten wir am Ende nach einer gescheiterten Implementierungsphase und abrupten Abbruch sogar nur 7 rote und einen grünen Test vorzuweisen. Bei dem Grünen frage ich momentan sogar immer noch warum ausgerechnet dieser Test überhaupt gelaufen ist.

Um also eine solche Situation zu vermeiden sollte man sich also am Anfang entscheiden wie man sein Dojo gemeinsam durchziehen will. Im weiteren werde ich jetzt eher auf die von mir favorisierte Variante mit striktem TDD eingehen, auch wenn mich eine Knobler-Session mit ausgeprägter Analysephase auch mal als Vergleichswert interessieren würde.

Wie gesagt: Ich bin ausdrücklich davon überzeugt, dass beide Lösungswege funktionieren können – je nach Problem mal besser und mal schlechter.

Striktes TDD und der einfachste Lösungsvorschlag gewinnt

Ein oft genanntes Argument der “Knobler”-Fraktion am TDD-Ansatz ist, dass nicht vorrausschauend entwickelt wird. Hey Jungs – das ist doch genau der Trick. Solange ich keine Anforderung für irgendwelche Dinge habe (nicht im Kopf oder auf dem Papier, sondern als Test) wird keine Komplexität hinzugefügt. Es wird dann behauptet, dass bei Test-first am Anfang sinnfreie Implementierungen gewählt werden und dass man diesen Code am Ende ganz offensichtlich sowieso wieder wegschmeißen würde. Aber das stimmt einfach nicht. Auch wenn ich immer mehr Tests hinzunehme und meine Implementierung immer generischer wird, so wird die vorherige Lösung letztlich immer ein Spezialfall der generischen Variante sein und geht somit nie verloren.

Gerade der Fokus auf diese minimal mögliche Generalsierung der aktuellen Implementierung sorgt dafür, dass der Algorithmus am Ende korrekt herausfällt. Das Knobeln kommt an dieser Stelle natürlich wieder in den Ablauf herein. Allerdings knobeln wir so an wesentlich kleineren und damit leichteren Problemen  – selbstverständlich nun viel öfter und in kürzeren Zyklen.

Bei zukünftigen Coding Dojos würde ich also gern als Regel sehen, dass der einfachste Vorschlag, der zu Grün führt implementiert wird.

Temposteigerung durch gruppenweises Anlegen von roten Tests

Zu bestimmten Zeitpunkten und insbesondere auch am Anfang von vielen Katas sieht man jedoch oft Implementierungsmuster die gleich eine ganze Klasse an Tests abdecken könnten. Wenn man so eine Idee hat, dann sollte man die natürlich auch nutzen und so das Tempo steigern. Anstatt aber diese Idee einfach zu programmieren würde ich erst die komplette Gruppe von Tests schreiben und sicherstellen, dass alle neuen Tests auch wirklich "rot sind. Dieser Shortcut ist aus meiner Sicht methodisch völlig unproblematisch, da zu diesem Zeitpunkt nur neue Anforderungen im System dokumentiert werden und diese dann als Begründung für neue Komplexität herangezogen werden können.

Aber auch hier sollte die selbe Regel gelten: Die leichteste Implementierung gewinnt. Wenn also ein Teilnehmer eine einfachere Lösung anbieten kann, dann wird die genommen.

Training durch Wiederholung

Wie Ilker in der Auswertung bereits gesagt hat, würde ich auch gern nochmal in der selben Truppe ein Dojo machen. Vielleicht ergibt sich das ja sogar beim nächsten OpenSpace. Denn selbstverständlich geht es beim Coding Dojo nicht nur um Code sondern auch um die beteiligten Menschen.
Obwohl wir am Ende keine Lösung vorweisen konnten, habe ich in der kurzen Zeit sehr viel über die Entwicklungsmethodik anderer Teilnehmer gelernt – ich denke das hat mir wirklich eine Menge gebracht.

Training durch Wiederholung – Reloaded

Da ein wichtiges Element bei Katas auch die Wiederholung ist (und mir im Zug langweilig ist), habe ich zusätzlich für mich selbst und andere noch eine aufgeräumtere Variante der Kata mit minimalen Commits in das Repository hochgeladen. Unter http://github.com/forki/DojoHamburg/commits/Karlsruhe kann man die Änderungen von unten nach oben genau nachvollziehen. Wenn jemand ein Stelle findet wo ich zu viel implementiert habe oder wo die Änderung nicht sinnvoll und einfach erscheint, dann würde ich mich freuen darüber diskutieren zu können.

Tags: ,

Friday, 18. June 2010


Bericht vom 2.ten .NET Coding Dojo in Hamburg

Filed under: C#,Coding Dojo,Kata — Steffen Forkmann at 18:52 Uhr

Am Mittwoch hat die .NET User Group Hamburg das zweite .NET Coding Dojo in wunderbarer Lage im Neuen Wall durchgeführt. Der Dank gilt diesmal Computer Futures, die uns freundlicherweise Raum, Beamer und Getränke zur Verfügung gestellt haben.

Ablauf

Nach einer kurzen Reflektion des letzten Treffens und Klärung der aufgetretenen Syntaxprobleme hat sich das Team dafür entschieden, die Kata.RomanNumerals zu implementieren. Wie beim ersten Treffen haben wir diese relativ einfache Kata auch wieder im Randori-Stil durchgeführt. Da das Team relativ gleich geblieben ist, konnten wir den Ablauf jedoch leicht erweitern. Um etwas mehr Schwung in die Test-Phase zu bringen, habe ich vorgeschlagen immer in der Rot-Phase zu rotieren. Zusätzlich haben wir git als Versionskontrollsystem im Einsatz gehabt und bei jeder Grün-Phase sowie nach Refactorings commited. Das Ergebnis kann auf meinem Github-Account bewundert werden.

Kata

Aus meiner Sicht bildet die Kata.RomanNumerals eine ideale Fortsetzung zur Kata.StringReplacer, die wir beim ersten Treffen hatten und ist praktisch perfekt mit Test-Driven Development lösbar. Insbesondere das nachträgliche Implementieren der scheinbar komplizierten Subtraktionsregel ist wunderbar anhand von wenigen Sonderfällen (= UnitTests) lösbar.

Was lief gut?
  • Die Rotation der Teilnehmer klappte wieder problemlos – Danke Jungs 🙂
  • TDD wurde als sehr erfolgreich für die Kata angesehen
  • Nahezu alle Teilnehmer waren überrascht wie einfach sich die Subtraktionsregel in TDD implementieren lässt
  • Die Randori-Form mit Rotation bei Rot sorgt für Aktivität
  • Es wurde immer versuchen die einfachste Lösung zu wählen
  • Die Rollen Driver, Co-Pilot und Publikum wurden klarer getrennt
  • Es wurde nach jedem implementierten Test in das git Repository commited
  • Ganz wichtig: Es hat wieder viel Spaß gemacht!
Was wollen wir besser machen?
  • Noch mehr Wert auf das Naming legen
    • Überraschenderweise hat sich kein Team getraut die Namenskonvention des ersten Teams zu verbessern
    • Insbesondere auch die Commit-Kommentare sind noch nicht sehr aussagekräftig
  • In den Refactoring-Phasen sollten die Tools (Resharper) besser genutzt werden
  • Die Refactorings könnten noch ausführlicher diskutiert werden
  • Von Anfang an externe Tastatur und Maus für den Laptop bereit stellen
  • Internetverbindung um Syntaxfrage schneller klären zu können
  • Parametrisierte Tests benutzen um weniger Test-Codierungsaufwand zu haben

Vielen Dank an alle Teilnehmer – wir sehen uns dann beim nächsten Dojo.

Tags: ,

Thursday, 20. May 2010


Bericht vom Ersten .NET Coding Dojo in Hamburg

Filed under: C#,Veranstaltungen — Steffen Forkmann at 6:37 Uhr

Gestern fand das erste .NET Coding Dojo in Hamburg statt und es war aus meiner Sicht ein voller Erfolg. Als erstes möchte ich mich an dieser Stelle bei der Firma masters of arts für die Räumlichkeit und natürlich bei allen Teilnehmer für die aktive Mitarbeit bedanken.

Erklärungen

Durchgeführt haben wir das Dojo im Randori-Stil, d.h. es gab einen Entwickler, einen “Co-Piloten” und das Publikum. Nach jeweils 5 Minuten bzw. jedem neuen Testfall wurden die Positionen mit neuen Teilnehmer aus dem Publikum getauscht.

Nach einer kurzen allgemeinen Einführung in das Thema “Coding Dojo” habe ich die Aufgabenstellungen der Kata.FizzBuzz und Kata.DictionaryReplacer vorgestellt. Durch kurze Abstimmung haben wir dann (vermutlich durch meine Wortwahl beeinflusst) die Kata.DictionaryReplacer gewählt.

Mit der Wahl dieser Kata war ich nicht ganz unglücklich, da wir DictionaryReplacer schon im Online Dojo durchgenommen haben und ich deshalb die Fallstricke schon etwas einschätzen konnte.

Kata.DictionaryReplacer

Create a method that takes a string and a dictionary,
and replaces every key in the dictionary pre and suffixed with a dollar sign,
with the corresponding value from the Dictionary.

Tests

input : "",
          dict empty
output: ""

input : "$temp$", 
           dict ["temp", "temporary"]
output: "temporary"

input : "$temp$ here comes the name $name$",
           dict ["temp", "temporary"] ["name", "John Doe"]
output : "temporary here comes the name John Doe"

[codingdojo.org]

Nach kurzer Einführung in die Vorgehensweise des Test-Driven Developments (TDD) und Diskussion über sinnvolles Naming ging es dann auch richtig in die Entwicklung. Die Kata eignet sich in dieser Form auch sehr schön um tatsächlich “Test first” zu arbeiten. Die Implementierung folgt quasi als logische Konsequenz.

Das Publikum

Interessant und ungleich komplizierter wurde es dann als wir eine zusätzliche Anforderung eingebaut haben. Da es sich bei der Kata um eine Art Templatesystem handelt liegt es nahe auch in den Values des Wörterbuchs neue Keys zu erlauben und somit eine beliebige Ersetzungstiefe zu erreichen. Diese Anforderung ist ein wunderbares Beispiel dafür wie sehr man mit Aufwandsabschätzungen daneben liegen kann. 😉

Guter Rat ist teuer

Die rekursive Ersetzung wurde noch sehr schnell gelöst, aber richtig schwer haben wir uns dann mit der Erkennung von zyklischen Ersetzungen und der daraus folgenden Endlosschleife getan. Nach und nach wurden immer kompliziertere Lösungsmöglichkeiten genannt, die aber in der gegebenen Zeit nicht fehlerfrei umgesetzt werden konnten. Als Folge haben wir immer noch einen Test “rot”. Wer Lust hat kann sich also die Quellen vom github Repository ziehen und als Hausaufgabe den verbleibenden Test “grün” machen.

In der Nachbetrachtung haben wir noch einige Sachen festgestellt:

Was lief gut?
  • Die Rotation der Teilnehmer klappte problemlos
  • Lösungsideen sprudelten förmlich aus dem Publikum
  • Interessante Edge-Cases wurden gefunden
  • Viele kleine Tipps (z.B. Resharper Shortcuts) wurden ausgetauscht
  • TDD wurde als erfolgreich für die Kata angesehen
  • Die Randori-Form sorgt für Aktivität
  • Ganz wichtig: Es hat Spaß gemacht!
Was wollen wir besser machen?
  • Schneller den ersten Test schreiben
  • Intensivere Diskussion des Interfaces
  • Noch mehr Wert auf das Naming legen
  • Versuchen die einfachste Lösung zu wählen
  • Mehr Wert auf Refactoring legen
    • wurde etwas vernachlässigt, da wir viel Zeit an der Endlosschleife verbraucht haben
  • Die Rollen Driver, Co-Pilot und Publikum klarer trennen
  • Nach jedem implementierten Testcase bzw. jeder Rotation der Teilnehmer in das git Repository einchecken
  • Von Anfang an externe Tastatur und Maus für den Laptop bereit stellen
  • Internetverbindung um Syntaxfrage schneller klären zu können

Als möglichen Termin für das Dojo haben wir jetzt grob jeweils den 3. Mittwoch im Monat vorgeschlagen. Über die Xing-Gruppe der .NET User Group Hamburg werden wir natürlich auch wieder entsprechende Einladungen verschicken.

Tags: , , ,

Tuesday, 13. April 2010


“FAKE – F# Make” and NaturalSpec released

Filed under: F#,FAKE - F# Make,Visual Studio — Steffen Forkmann at 8:06 Uhr

Yesterday Microsoft released the RTM versions of Visual Studio 2010, .NET Framework 4.0 and F# 2.0.0.0 and so it is time to announce the first official releases of “Fake – F# Make” and NaturalSpec. Both projects are now compatible with Visual Studio 2010 RC and RTM and the corresponding F# versions.

Fake – F# Make version 1.0.0

"FAKE – F# Make" is a build automation system, which is intended to provide a much better tooling support than XML-based build languages like MSBuild or NAnt. Due to its integration in F#, all benefits of the .NET Framework and functional programming can be used, including the extensive class library, powerful debuggers and integrated development environments like Visual Studio 2008, Visual Studio 2010 or SharpDevelop, which provide syntax highlighting and code completion.

Like F# itself the new build language was designed to be succinct, typed, declarative, extensible and easy to use.

NaturalSpec version 1.0.0

NaturalSpec is a UnitTest framework based on NUnit and completely written in F# – but you don’t have to learn F# to use it. The idea is that you can write your spec mostly in a natural language like in the following sample:

[<Scenario>]

let “When removing an element from a list it should not contain the element“() =

  Given [1;2;3;4;5]                 // "Arrange" test context

    |> When removing 3              // "Act"

    |> It shouldn’t contain 3       // "Assert"

    |> It should contain 4          // another assertion

    |> It should have (Length 4)    // Assertion for length

    |> It shouldn’t have Duplicates // it contains duplicates ?

    |> Verify                       // Verify scenario

If you have any questions about the projects feel free to contact me.

Tags: , , ,

Sunday, 8. November 2009


"Getting started" with NaturalSpec – (Updated 08.11.2009)

Filed under: .NET,F#,NaturalSpec — Steffen Forkmann at 10:48 Uhr

In my last article (Introducing NaturalSpec – A Domain-specific language (DSL) for testing) I used NaturalSpec in two small samples. This time I will show how we can set up a NaturalSpec environment to write our first automatically testable scenarios.

1. Choosing an IDE

The first step is to choose an integrated development environment for NaturalSpec. At the current project status you should be able to use NaturalSpec with Visual Studio 2008, Visual Studio 2010 beta 2, the freely available Visual Studio 2008 Shell or the free IDE SharpDevelop 3.0.

2. Installing the testing framework

As NaturalSpec uses NUnit as the underlying testing framework we have to install NUnit 2.5. I also recommend installing TestDriven.Net in order to get a Unit Test runner within Visual Studio.

3. Installing F#

NaturalSpec is completely written in F# and all specs will also be written in F#. This doesn’t imply you have to learn programming in F# but we need the F# compiler to get things working. You can download the F# October 2009 CTP from the Microsoft F# Developer Center.

4. Downloading the latest version of NaturalSpec

You can download a .zip with the latest NaturalSpec libraries from GoogleCode.

5. Creating a spec

This part is written for using Visual Studio 2008. If you use SharpDevelop or Visual Studio 2008 Shell this might differ in some detail.

Start Visual Studio 2008 and create a new F# class library.

Creating a spec project

Rename Module1.fs in ListSpec.fs and delete script.fsx from the project:

Solution explorer

Create a folder “Lib” and unzip the NaturalSpec libraries into it.

Add NaturalSpec.dll and nunit.framework.dll as references to your project:

Adding project references

Copy the following code into ListSpec.fs:

module ListSpec
open NaturalSpec

[<Scenario>]
let When_removing_an_3_from_a_small_list_it_should_not_contain_3() =
  Given [1;2;3;4;5]
    |> When removing 3
    |> It shouldn't contain 3
    |> Verify

If you have TestDriven.Net installed you can run your spec via right click in the solution explorer:

Run spec with TestDriven.net

If you don’t like the TestDriven.Net test runner you might want to use the NUnit GUI runner. The output should look like:

NUnit Gui runner

In addition the test runner should produce a Spec output file with the name “Spec.txt” within the same folder.

Summary

In a minimal environment you need SharpDevelop, the F# compiler, NUnit and the NaturalSpec libraries for using NaturalSpec.

In the next post I will show how you can use NaturalSpec to create a spec for C# projects.

Tags: , , , , ,

Friday, 6. November 2009


Observing global hotkeys in C# / F#

Filed under: C#,F# — Steffen Forkmann at 11:08 Uhr

I recently had the problem to register a global hotkey, but my “old” Win32-API calls didn’t work with WPF. I looked around the web and found the “Managed Windows API”, but I didn’t want to add another external dependency to my project, so I extracted the core functions for registering hotkeys and condensed the code to a new version.

As the original “Managed Windows API” is licensed by the GNU Lesser General Public License (LGPL) I want to provide my modifications here.

First we need a Window which can dispatch the window messages to our event handlers:

/// <summary>

/// A Win32 native window that delegates window messages to

/// handlers. So several

/// components can use the same native window to save

/// "USER resources". This class

/// is useful when writing your own components.

/// </summary>

public sealed class EventDispatchingNativeWindow : NativeWindow

{

    private static readonly Object MyLock = new Object();

    private static EventDispatchingNativeWindow _instance;

 

    /// <summary>

    /// Create your own event dispatching window.

    /// </summary>

    public EventDispatchingNativeWindow()

    {

        CreateHandle(new CreateParams());

    }

 

    /// <summary>

    /// A global instance which can be used by components

    /// that do not need their own window.

    /// </summary>

    public static EventDispatchingNativeWindow Instance

    {

        get

        {

            lock (MyLock)

            {

                return

                  _instance ??

                     (_instance =

                       new EventDispatchingNativeWindow());

            }

        }

    }

 

    /// <summary>

    /// Attach your event handlers here.

    /// </summary>

    public event WndProcEventHandler EventHandler;

 

    /// <summary>

    /// Parse messages passed to this window and send

    /// them to the event handlers.

    /// </summary>

    /// <param name="m">A System.Windows.Forms.Message

    /// that is associated with the

    /// current Windows message.</param>

    protected override void WndProc(ref Message m)

    {

        bool handled = false;

        if (EventHandler != null)

            EventHandler(ref m, ref handled);

        if (!handled)

            base.WndProc(ref m);

    }

}

Now we can write our global hotkey handler class:

/// <summary>

/// Specifies a class that creates a global keyboard hotkey.

/// </summary>

public class GlobalHotkey

{

    private static readonly Object MyStaticLock = new Object();

    private static int _hotkeyCounter = 0xA000;

 

    private readonly int _hotkeyIndex;

    private readonly IntPtr _hWnd;

 

    /// <summary>

    /// Initializes a new instance of this class.

    /// </summary>

    /// <param name="keys">The keys.</param>

    /// <param name="ctrl">if <c>true</c> [CTRL].</param>

    /// <param name="alt">if <c>true</c> [alt].</param>

    /// <param name="shift">if <c>true</c> [shift].</param>

    /// <param name="winKey">if <c>true</c> [win key].</param>

    public GlobalHotkey(Keys keys, bool ctrl,

               bool alt, bool shift, bool winKey)

    {

        KeyCode = keys;

        Ctrl = ctrl;

        Alt = alt;

        Shift = shift;

        WindowsKey = winKey;

        EventDispatchingNativeWindow.Instance.EventHandler

                += NwEventHandler;

        lock (MyStaticLock)

        {

            _hotkeyIndex = ++_hotkeyCounter;

        }

        _hWnd = EventDispatchingNativeWindow.Instance.Handle;

        Enable();

    }

 

    /// <summary>

    /// The key code of the hotkey.

    /// </summary>

    public Keys KeyCode { get; private set; }

 

    /// <summary>

    /// Whether the shortcut includes the Control modifier.

    /// </summary>

    public bool Ctrl { get; private set; }

 

    /// <summary>

    /// Whether this shortcut includes the Alt modifier.

    /// </summary>

    public bool Alt { get; private set; }

 

    /// <summary>

    /// Whether this shortcut includes the shift modifier.

    /// </summary>

    public bool Shift { get; private set; }

 

    /// <summary>

    /// Whether this shortcut includes the Windows key modifier.

      /// </summary>

    public bool WindowsKey { get; private set; }

 

    ~GlobalHotkey()

    {

        Disable();

        EventDispatchingNativeWindow.Instance.EventHandler

            -= NwEventHandler;

    }

 

    /// <summary>

    /// Enables the hotkey. When the hotkey is enabled,

    /// pressing it causes a

    /// <c>HotkeyPressed</c> event instead of being

    /// handled by the active application.

    /// </summary>

    private void Enable()

    {

        // register hotkey

        int fsModifiers = 0;

        if (Shift) fsModifiers += ModShift;

        if (Ctrl) fsModifiers += ModControl;

        if (Alt) fsModifiers += ModAlt;

        if (WindowsKey) fsModifiers += ModWin;

        bool success =

           RegisterHotKey(_hWnd, _hotkeyIndex,

                fsModifiers, (int) KeyCode);

 

        if (!success)

            throw new

              Exception(

                "Could not register hotkey (already in use).");

    }

 

    /// <summary>

    /// Disables this instance.

    /// </summary>

    private void Disable()

    {

        // unregister hotkey

        UnregisterHotKey(_hWnd, _hotkeyIndex);

    }

 

    /// <summary>

    /// Occurs when the hotkey is pressed.

    /// </summary>

    public event EventHandler HotkeyPressed;

 

    private void NwEventHandler(ref Message m, ref bool handled)

    {

        if (handled) return;

        if (m.Msg != WmHotkey ||

                m.WParam.ToInt32() != _hotkeyIndex)

            return;

        if (HotkeyPressed != null)

            HotkeyPressed(this, EventArgs.Empty);

        handled = true;

    }

 

    #region PInvoke Declarations

 

    private const int ModAlt = 0x0001;

    private const int ModControl = 0x0002;

    private const int ModShift = 0x0004;

    private const int ModWin = 0x0008;

    private const int WmHotkey = 0x0312;

 

    [DllImport("user32.dll", SetLastError = true)]

    private static extern bool RegisterHotKey(IntPtr hWnd,

          int id, int fsModifiers, int vlc);

 

    [DllImport("user32.dll", SetLastError = true)]

    private static extern bool UnregisterHotKey(IntPtr hWnd,

          int id);

 

    #endregion

}

Now we can easily register a global hotkey or use it as an observable in F#:

/// system-wide keyboard hook

let hotkey = new GlobalHotkey(Keys.Q,true,false,false,false)

let hookObserver =

  hotkey.HotkeyPressed 

    |> Observable.subscribe (fun _ -> printfn "Hotkey pressed")

Tags: , , , ,

Monday, 24. August 2009


SOLID Part I – The Open/Closed-Principle – C# vs. F#

Filed under: C#,English posts,F#,Veranstaltungen — Steffen Forkmann at 11:43 Uhr

Friday I attended the .NET BootCamp “NHibernate vs. Entity Framework” in Leipzig and as always it was a pleasure for me being there. Afterwards I had a nice talk with my friend Alexander Groß about the Open/Closed Principle. I didn’t really care about this principle before, but now I think it’s really a nice idea:

“In object-oriented programming, the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be modified without altering its source code.”

[Wikipedia]

If we follow this principle we get lot’s of small and testable classes. I want to demonstrate this with a simple spam checker for mails.

Let’s say our mail class has only a sender, a recipient, a subject and the mail body:

public class EMail

{

    public string Sender { get; set; }

    public string Recipient { get; set; }

    public string Subject { get; set; }

    public string Body { get; set; }

 

    public EMail(string sender, string recipient,

        string subject, string body)

    {

        Sender = sender;

        Recipient = recipient;

        Subject = subject;

        Body = body;

    }

}

 

public enum SpamResult

{

    Spam,

    Ok,

    Unknown

}

Now we want to know if a mail is spam or not. Of course we need some rules and some kind of “rule checker” to decide this. Here is a very naïve implementation for this:

public class RuleChecker

{

    public SpamResult CheckMail(EMail mail)

    {

        var result = TestRule1(mail);

        if(result != SpamResult.Unknown)

            return result;

 

        result = TestRule2(mail);

        if (result != SpamResult.Unknown)

        return result;

 

        // …

        return SpamResult.Unknown;

    }

 

    private SpamResult TestRule1(EMail mail)

    {

        // I don’t care about the concrete rules

    }

 

    private SpamResult TestRule2(EMail mail)

    {

        // I don’t care about the concrete rules

    }

}

It is obvious that this implementation breaks the Open/Closed Principle. Every time someone comes up with a new anti-spam rule or the rule priorities change I have to modify the code in CheckMail(). Another problem here is that I can’t test CheckMail() isolated from the concrete rules.

With the help of the Open/Closed Principle our implementation could look like this:

public interface ISpamRule

{

    SpamResult CheckMail(EMail mail);

}

 

public class RuleChecker

{

    private readonly IEnumerable<ISpamRule> _rules;

 

    public RuleChecker(IEnumerable<ISpamRule> rules)

    {

        _rules = rules;

    }

 

    public SpamResult CheckMail(EMail mail)

    {

        foreach (var rule in _rules)

        {

            var result = rule.CheckMail(mail);

            if (result != SpamResult.Unknown)

                return result;

        }

        return SpamResult.Unknown;

    }

}

Now you could easily write isolated UnitTests for RuleChecker.CheckMail() and for every new rule.

You get the your concrete RuleChecker by calling the constructor with a list of rules:

class MyFirstRule : ISpamRule

{

    public SpamResult CheckMail(EMail mail)

    {

        // I don’t care about this

    }

}

 

class MySecondRule : ISpamRule

{

    public SpamResult CheckMail(EMail mail)

    {

        // I don’t care about this

    }

}

// …

var ruleChecker =

    new RuleChecker(

        new List<ISpamRule>

        {

            new MyFirstRule(),

            new MySecondRule(),

            // …

        });

Alex please correct me if I’m wrong, but I think this is what you had in mind Friday.

As stated before, we end up writing lot’s of very small classes – mostly with only one (public) method. I think this is some kind of functional approach, the only question is how we glue our code entities together. Let’s look at the corresponding F# implementation:

type EMail =

  { Sender: string;

    Recipient: string;

    Subject: string;

    Body: string}

 

type SpamResult =

  | Spam

  | OK

  | Unknown

 

let checkMail rules (mail:EMail) =

  let rec checkRule rules =

    match rules with

    | rule::rest ->

      match rule mail with

      | Unknown -> checkRule rest

      | _ as other -> other

    | [] –> Unknown

 

  checkRule rules

The signature of checkMail is (EMail -> SpamResult) list -> EMail –> SpamResult, which means it takes a list of rules (as above the order is important) and a EMail and returns the SpamResult. In addition I exchanged the explicit foreach loop with a tail recursion to make it look more functional.

If I want a concrete rule checker I could use partial application:

let myFirstRule mail =

  // I don’t care about this

let mySecondRule mail =

  // I don’t care about this

// val ruleChecker :  (EMail –> SpamResult)

let ruleChecker =

  checkMail

    [ myFirstRule;

      mySecondRule]

As you can see the F# implementation is nearly the same as the C# implementation, just without explicitly wrapping our public method in classes. If we would use Reflector we would see that the F# compiler is building the classes around our functions. One could say if we follow the Open/Closed Principle we come to functional code or the other way around if we write functional code we automatically apply the Open/Closed Principle. I think that’s why I really didn’t care about this before.

Appendix

After thinking about this implementation and the extra type hint (see mail:EMail) I came up with a slightly more generic implementation:

type SpamResult =

  | Spam

  | OK

 

let checkRules rules element =

  let rec checkRule rules =

    match rules with

    | rule::rest ->

      match rule element with

      | None -> checkRule rest

      | _ as other -> other

    | [] –> None

 

  checkRule rules

Here I deleted the enum value for SpamResult.Unknown and used the standard None option. As a consequence the signature changed to:  val checkRules : (‘a -> ‘b option) list -> ‘a -> ‘b option. The function still takes a list of rules and a element and returns a option value. Now the checkRules function works with every kind of rule result and takes arbitrary elements.

Tags: , , , ,