Thursday, October 14, 2010

A Pinch of Functional in my C# - An Everyday Example

I'm working on a codebase that, like many other code bases,  has a number of data access objects(DAOs) that all inherit a common superclass. The other day I got tired of looking this pattern of code repeated a lot in the DAOs:
    1        public MyDTO GetMyDTO(...)
    2         {
    3             DataContext DB = NewDBContext;
    4             try
    5             {
    6                 DB.Connection.Open();
    7                 //Fetch something from the DB and return it
    8             }
    9             finally
   10             {
   11                 if (DB.Connection.State == ConnectionState.Open)
   12                     DB.Connection.Close();
   13             }
   14         }

I wanted the creation of the DBContext and the handling of the connection to be factored into somewhere reusable. So I applied the functional "suround with" pattern and introduced this method in the superclass:
    1        protected TReturn UsingDBConnection<TReturn>(Func<DataContext, TReturn> func)
    2         {
    3             DataContext DB = NewDBContext;
    4             try
    5             {
    6                 DB.Connection.Open();
    7                 return func(DB);
    8             }
    9             finally
   10             {
   11                 if (DB.Connection.State == ConnectionState.Open)
   12                     DB.Connection.Close();
   13             }
   14         }
and the DAO code then turns into this:
    1        public MyDTO GetMyDTO(...)
    2         {
    3             return UsingDBConnection(DB =>
    4             {
    7                 //Fetch something from the DB and return it
    7             });
    8         }

C# has supported this for years now, so why am I posting it? -Because I wish I saw more of this type of code. To me it's easy to read and I get to reuse the common part.


Saturday, October 2, 2010

Notes from getting Scala running on .NET

I just spend an evening getting Scala to run on .NET 4.0. Here my notes:

Scala 2.8.0

I started downloading Scala 2.8.0-final as a zip file (), and unpacking it to my scala playground directory. That gave me:
PS C:\Scala-playground\scala-2.8.0.final> tree
Folder PATH listing for volume OSDisk
Volume serial number is 00690066 6A5B:A532
C:.
+---bin
+---doc
¦   +---sbaz
¦   +---sbaz-setup
+---lib
+---meta
¦   +---cache
+---misc
¦   +---sbaz
¦   ¦   +---config
¦   ¦   +---descriptors
¦   +---sbaz-testall
¦   ¦   +---tests
¦   +---scala-devel
¦   ¦   +---plugins
¦   +---scala-tool-support
¦       +---a2ps
¦       +---bash-completion
¦       +---bluefish
¦       +---context
¦       ¦   +---Highlighters
¦       ¦   +---Template
¦       +---emacs
¦       ¦   +---contrib
¦       +---enscript
¦       +---geshi
¦       +---intellij
¦       +---jedit
¦       ¦   +---console
¦       ¦   ¦   +---commando
¦       ¦   +---modes
¦       +---latex
¦       +---notepad-plus
¦       +---scite
¦       +---subethaedit
¦       ¦   +---artwork
¦       ¦   +---Scala.mode
¦       ¦       +---Contents
¦       ¦           +---Resources
¦       ¦               +---English.lproj
¦       ¦               +---Scripts
¦       +---textmate
¦       ¦   +---Bundles
¦       +---textpad
¦       +---textwrangler
¦       +---ultraedit
¦       +---vim
¦           +---ftdetect
¦           +---indent
¦           +---plugin
¦           +---syntax
+---src

I then went on to install the Scala msil extension (i.e. the scala .NET compiler and runtime) as follows:
PS C:\Scala-playground\scala-2.8.0.final> bin/sbaz.bat install scala-msil

Then, following the "official" instructions on running scala on .NET (http://www.scala-lang.org/node/168), I copied mscorlib.dll to the scala lib folder:
PS C:\Scala-playground\scala-2.8.0.final> copy C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll .\lib

I was now ready to try to compile something. E.g. this very simple hello world program using a little bit of .NET, namely Console.WriteLine:

import System.Console object test extends Application {   Console.WriteLine("Hello world!") }

I tried to compile it like this:
PS C:\Scala-playground\hello.net> ..\scala-2.8.0.final\bin\scalac.bat -target:msil .\test.scala

but got this error:
scala.tools.nsc.MissingRequirementError: class scala.runtime.VolatileBooleanRef not found.
        at scala.tools.nsc.symtab.Definitions$definitions$.getModuleOrClass(Definitions.scala:513)
        at scala.tools.nsc.symtab.Definitions$definitions$.getClass(Definitions.scala:471)
        at scala.tools.nsc.symtab.Definitions$definitions$.newValueClass(Definitions.scala:620)
        at scala.tools.nsc.symtab.Definitions$definitions$.BooleanClass(Definitions.scala:92)
        at scala.tools.nsc.symtab.Definitions$definitions$.initValueClasses(Definitions.scala:643)
        at scala.tools.nsc.symtab.Definitions$definitions$.init(Definitions.scala:787)
        at scala.tools.nsc.Global$Run.(Global.scala:597)
        at scala.tools.nsc.Main$.process(Main.scala:107)
        at scala.tools.nsc.Main$.main(Main.scala:122)
        at scala.tools.nsc.Main.main(Main.scala)
error: fatal error: class scala.runtime.VolatileBooleanRef not found.

I tried like this to point out where mscorlib and the scala runtime dlls are:
PS C:\Scala-playground\hello.net> ..\scala-2.8.0.final\bin\scalac.bat -target:msil -Xassem-extdirs ..\scala-2.8.0.final\lib .\test.scala
scala.tools.nsc.MissingRequirementError: class scala.runtime.VolatileBooleanRef not found.
        at scala.tools.nsc.symtab.Definitions$definitions$.getModuleOrClass(Definitions.scala:513)
        at scala.tools.nsc.symtab.Definitions$definitions$.getClass(Definitions.scala:471)
        at scala.tools.nsc.symtab.Definitions$definitions$.newValueClass(Definitions.scala:620)
        at scala.tools.nsc.symtab.Definitions$definitions$.BooleanClass(Definitions.scala:92)
        at scala.tools.nsc.symtab.Definitions$definitions$.initValueClasses(Definitions.scala:643)
        at scala.tools.nsc.symtab.Definitions$definitions$.init(Definitions.scala:787)
        at scala.tools.nsc.Global$Run.(Global.scala:597)
        at scala.tools.nsc.Main$.process(Main.scala:107)
        at scala.tools.nsc.Main$.main(Main.scala:122)
        at scala.tools.nsc.Main.main(Main.scala)
error: fatal error: class scala.runtime.VolatileBooleanRef not found.
..same error.

Then I resorted to frantic googling, but ended up deciding to downgrade the mscorlib.dll to 2.0, and to 1.1. But in both cases I got same depressing result.
Finally I decided to downgrade to scala 2.7.7.

Scala 2.7.7

I downloaded scala 2.7.7 unzipped it and got:
PS C:\Scala-playground\scala-2.7.7.final> tree
Folder PATH listing for volume OSDisk
Volume serial number is 00690066 6A5B:A532
C:.
+---bin
+---doc
¦   +---sbaz
¦   +---sbaz-setup
+---lib
+---meta
¦   +---cache
+---misc
¦   +---sbaz
¦   ¦   +---descriptors
¦   +---sbaz-testall
¦   ¦   +---tests
¦   +---scala-tool-support
¦       +---a2ps
¦       +---bluefish
¦       +---context
¦       ¦   +---Highlighters
¦       ¦   +---Template
¦       +---emacs
¦       ¦   +---contrib
¦       +---enscript
¦       +---geshi
¦       +---intellij
¦       +---jedit
¦       ¦   +---console
¦       ¦   ¦   +---commando
¦       ¦   +---modes
¦       +---latex
¦       +---notepad-plus
¦       +---scite
¦       +---subethaedit
¦       ¦   +---artwork
¦       ¦   +---Scala.mode
¦       ¦       +---Contents
¦       ¦           +---Resources
¦       ¦               +---English.lproj
¦       ¦               +---Scripts
¦       +---textmate
¦       ¦   +---Bundles
¦       +---textpad
¦       +---textwrangler
¦       +---ultraedit
¦       +---vim
¦           +---ftdetect
¦           +---indent
¦           +---plugin
¦           +---syntax
+---src
The I went through copying mscorlib and installing scala-msil again:
PS C:\Scala-playground\scala-2.7.7.final> copy C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll .\lib
PS C:\Scala-playground\scala-2.7.7.final> .\bin\sbaz.bat install scala-msil
planning to install: scala-msil/2.7.7.final
Installing...

Then I tried compilling again:
PS C:\Scala-playground\hello.net> ..\scala-2.7.7.final\bin\scalac-net.bat .\test.scala
PS C:\Scala-playground\hello.net> ls


    Directory: C:\Scala-playground\hello.net


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        30-09-2010     21:59            target
-a---        30-09-2010     22:33       3863 test.msil
-a---        30-09-2010     21:52        100 test.scala

which went well. The scala compiler made a .msil file. Yeah.

Next step was turning that .msil into an .exe:
PS C:\Scala-playground\hello.net> C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe .\test.msil

Microsoft (R) .NET Framework IL Assembler.  Version 4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.
Assembling '.\test.msil'  to EXE --> '.\test.exe'
Source file is ANSI

Assembled method test::$tag
Assembled method test::main
Assembled method test$::.ctor
Assembled method test$::.cctor
Assembled method test$::$tag
Assembled method test$::main
Assembled global method Main
Creating PE file

Emitting classes:
Class 1:        test
Class 2:        test$

Emitting fields and methods:
Global  Methods: 1;
Class 1 Methods: 2;
Class 2 Fields: 1;      Methods: 4;
Resolving local member refs: 8 -> 8 defs, 0 refs, 0 unresolved

Emitting events and properties:
Global
Class 1
Class 2
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully

Which gave:
PS C:\Scala-playground\hello.net> ls


    Directory: C:\Scala-playground\hello.net


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        30-09-2010     21:59            target
-a---        30-09-2010     22:35       2560 test.exe
-a---        30-09-2010     22:33       3863 test.msil
-a---        30-09-2010     21:52        100 test.scala

So I tried running the program:
PS C:\Scala-playground\hello.net> .\test.exe

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'predef, Version=0.0.0.0, Culture=
neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
   at Main(String[] args)

but missed the predef assembly which is part of the scala-msil extension. To get passed that I simply copied all dlls from the Scala lib folder and ran again:
PS C:\Scala-playground\hello.net> mv .\test.exe .\target
PS C:\Scala-playground\hello.net> cp ..\scala-2.7.7.final\lib/*.dll .\target
PS C:\Scala-playground\hello.net> cd .\target
PS C:\Scala-playground\hello.net\target> ls

    Directory: C:\Scala-playground\hello.net\target


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        30-09-2010     22:30    2070528 mscorlib.dll
-a---        30-09-2010     22:30    1180160 predef.dll
-a---        30-09-2010     22:30       5632 scalaruntime.dll
-a---        30-09-2010     22:35       2560 test.exe
PS C:\Scala-playground\hello.net\target> .\test.exe
Hello world!

Success! but only on the next to newest Scala version. Either way I had fun :-)

Saturday, September 25, 2010

Spec Style Unit Tests in C#

Spec style unit tests are unit tests that focus on making the specs clear, and then relating some test code to each part of the spec. The Specs Scala unit test framework is really good at that (e.g. check this earlier post), but I want to be able to do the same in C#.


Lets look at an example: A method for deciding whether a given year is a leap year. The rules for leap years are:


A leap year should
    be any year divisible by 400
    but not other years divisible by 100
    and all other years divisible by 4


In other words the above are the specs for the method. So I would like that to be clear from the unit test. I would also like the unit test to make it clear what test code corresponds to what part of the spec. Therefore I would like the spec to be part of the test, and the test code to be mixed right into that spec text. Something like:


"A leap year" should
{
  "be any year divisible by 400" asIn
{
// test code here
}
  "but not other years divisible by 100" asIn
{
// test code here
}
  "and all other years divisible by 4" asIn
{
// test code here
}
}


such that the spec is clearly visible as the strings, and such that the 'asIn' indicates that the code in the following scope tests the part of the spec right before the 'asIn'. To achieve something close to this I've made three simple extension methods on string: 'should', 'asIn' and 'andIn'. Each one of these extension methods take a delegate as an argument. That makes it possible to write this code:

   16             "A leap year".should(() =>
   17             {
   18                 "be any year divisible by 400".asIn(() =>
   19                 {
   20                     // Test code here
   21 
   22                 })
   23                 .andIn(() =>
   24                 {
   25                     // More test code
   26                 });
   27 
   28                 "but not other years divisible by 100".asIn(() =>
   29                 {
   30                     // Test code here
   31                 });
   32 
   33                 "and all other years divisible by 4".asIn(() =>
   34                 {
   35                     // Test code here
   36                 })
   37 

Because this is C# there I need to the dots and the arrows ( ()=> ) in there, but I still think the spec is pretty clearly visible. The extension methods themselves are very simple: They basically just execute the delegate passed to them, which means that all the test code snippets in the above will be executed. The complete code for the extension methods is:




    1 using System;
    2 
    3 namespace Specs
    4 {
    5     public static class SpecExtensions
    6     {
    7         public static void should(this string unitUnderTest,
    8                                   Action executableSpecification)
    9         {
   10             Console.WriteLine(unitUnderTest + " should");
   11             executableSpecification();
   12         }
   13 
   14         public static string asIn(this string readableSpecification,
   15                                   Action executableSpecification)
   16         {
   17             Console.WriteLine(@"    " + readableSpecification);
   18             return RunExecutableSpecification(
   19                     readableSpecification, executableSpecification);
   20         }
   21 
   22         public static string andIn(
   23             this string readableSpecification,
   24             Action executableSpecification)
   25         {
   26             return RunExecutableSpecification(
   27                     readableSpecification, executableSpecification);
   28         }
   29 
   30         private static string RunExecutableSpecification(
   31             string readableSpecification,
   32             Action executableSpecification)
   33         {
   34             executableSpecification();
   35             return readableSpecification;
   36         }
   37     }
   38 }


Combining that with NUnit, the test for my leap year checker becomes:




    1 using NUnit.Framework;
    2 
    3 namespace Specs.Test
    4 {
    5     [TestFixture]
    6     public class LeapYearTest
    7     {
    8         [Test]
    9         public void LeapYearSpec()
   10         {
   11             "A leap year".should(() =>
   12             {
   13                 "be any year divisible by 400".asIn(() =>
   14                 {
   15                     Assert.That(LeapYearChecker.IsLeapYear(0),
   16                                 Is.True);
   17                     Assert.That(LeapYearChecker.IsLeapYear(400),
   18                                 Is.True);
   19                     Assert.That(LeapYearChecker.IsLeapYear(800),
   20                                 Is.True);
   21                 })
   22                 .andIn(() =>
   23                 {
   24                     Assert.That(LeapYearChecker.IsLeapYear(-400),
   25                                 Is.False);
   26                 });
   27 
   28                 "but not other years divisible by 100".asIn(() =>
   29                 {
   30                     Assert.That(LeapYearChecker.IsLeapYear(100),
   31                                 Is.False);
   32                     Assert.That(LeapYearChecker.IsLeapYear(100),
   33                                 Is.False);
   34                     Assert.That(LeapYearChecker.IsLeapYear(200),
   35                                 Is.False);
   36                     Assert.That(LeapYearChecker.IsLeapYear(1000),
   37                                 Is.False);
   38                 });
   39 
   40                 "and all other years divisible by 4".asIn(() =>
   41                 {
   42                     for (int i = 0; i < 100; i += 4)
   43                     {
   44                         Assert.That(LeapYearChecker.IsLeapYear(i),
   45                                     Is.True);
   46                     }
   47                 })
   48                 .andIn(() =>
   49                 {
   50                     for (int i = 1600; i < 1700; i += 4)
   51                     {
   52                         Assert.That(LeapYearChecker.IsLeapYear(i),
   53                                     Is.True);
   54                     }
   55                 })
   56                 .andIn(() =>
   57                 {
   58                     for (int i = 1601; i < 1700; i += 4)
   59                     {
   60                         Assert.That(LeapYearChecker.IsLeapYear(i),
   61                                     Is.False);
   62                     }
   63                 });
   64             });
   65         }
   66     }
   67 

The specs are not as easily visible once all the code is there, but I still think its easy to find the specs. What do you think? Is there too much clutter of dots and arrows and stuff? Is the calling back and forth between the test and extension methods too strange? I'm on the fence. One part me really, really likes this. One part of me really, really doesn't.
Oh, and for completeness the code under test is:




    1    public static class LeapYearChecker
    2     {
    3         public static bool IsLeapYear(int year)
    4         {
    5             return year >= 0 &&
    6                 (year % 400 == 0 ||
    7                 (year % 4 == 0 && year % 100 != 0));
    8         }
    9     }