c

Silverlight unit testing with NUnit: yes you can (without hacks)!

It may be obvious for most of you, but it took a while to my caveman brain to realize this, so I figured I could post it for other cavemen. You (we) have got an excuse though: the short release cycle of Silverlight means that most stackoverflow questions and blog posts on the subject are out-of-date and refer to older versions of Silverlight (<=3) when what I describe was not possible.

Up to Silverlight 3 you had to use a Silverlight-specific unit testing tool, like the Silverlight Toolkit framework. These tools are quite awesome and have been fundamental, but it’s nice to have the full power of NUnit (or xUnit & co.) at disposal. In addition to the community and tooling support, it’s practical to use the same tool you already use for other .NET projects.

The game changer is called binary assembly compatibility, brought by Silverlight 4. In a few words this means that you can add a reference to a Silverlight assembly from a “full” .NET project (provided that you don’t use any Silverlight-only class).

If your application is correctly layered (for ex. with MVVM) in most cases it’s trivial to keep views and viewModels/models in separate assemblies. ViewModels and models usually don’t reference any Silverlight-only class (otherwise you may have a code smell!) and are 100% compatible with .NET, so testing them with NUnit is as easy as

  • create a .NET class library in your solution
  • add a reference to NUnit (NuGet it!)
  • add a reference to your model and/or viewModel assemblies
  • write your unit tests
  • run them with NUnit

no tweaking or hacking required and works fine with F# assemblies as well.

It is typical for views to use Silverlight-only classes, but this is generally not a problem because it doesn’t make much sense to unit-test them anyways as they are mostly XAML with very little amounts of code-behind.

Free tip: if you want to test internal classes and methods you can add the InternalsVisibleTo attribute to the target assembly.

Happy testing!

bear

Dynamic member binding in Silverlight 4

UPDATE: Xavier Decoster already wrote a nice article on this topic some time ago. Please check it out! (Note to self: improve google skills)

First, let me say that I’ll take the long route, so if you are already familiar with dynamic typing in C# you can probably jump straight to the last section. Otherwise read on, you may learn something cool that is not used every day but can save you in some situations.

In the [not so] old days of Silverlight 3 if you wanted to dynamically create a class you had to emit intermediate language instructions, etc. Definitely not so easy. Silverlight 4 (with C# 4.0) introduced support for dynamics and simplified this a lot.

Straight from the DynamicObject documentation, this simple implementation of a dynamic dictionary uses an internal dictionary to store string/object pairs where the key is the member name and value is its associated value.

public class DynamicDictionary : DynamicObject
{
    Dictionary<string, object> dictionary =
        new Dictionary<string, object>();

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }

    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }
}

In a DynamicObject you have two methods (TryGetMember and TrySetMember) that are invoked every time someone tries to access the objects’ members. In this particular implementation, when this code is executed

dynamic myDynamicObject = new DynamicDictionary();
myDynamicObject.FirstName = "John";
myDynamicObject.Age = 18;

two pairs “FirstName”/”John” and “Age”/18 are stored in the internal dictionary. On the other hand when you do

string test = myDynamicObject.FirstName;

instead of calling the getter of FirstName (like any statically typed object would do), TryGetMember is invoked and the value corresponding to key “FirstName” is looked up from the internal dictionary.

The dynamic keyword tells the compiler that the member will be looked up at runtime, so you can set/get any member you want and the compiler won’t complain: he knows the members will be resolved while the program is running.

The binding problem

Now there is only a small problem with this approach (and it’s the whole point of this post): if you create a binding that targets a dynamic member you’ll get an error. It looks like the Silverlight binding engine “cannot discover” dynamic properties.

For example this does not work:

public dynamic MyDynamicDictionary {  get;     set; }

// ...

MyDynamicDictionary = new DynamicDictionary();
MyDynamicDictionary.Label = "Hello, I'm dynamic!";
 <Button Content="{Binding MyDynamicDictionary.Label}"/> 

brokenBinding

If you look at the output:

System.Windows.Data Error: BindingExpression path error: 'Label' property not found on 'SilverlightApplication22.DynamicDictionary'

Indexed binding to the rescue

Telerik’s Vladimir Enchev explains on his blog how this approach can be used to implement a dataTable-like structure that can back for ex. a datagrid. The clever bit is that he added to the DynamicDictionary the [] indexer:

public object this[string columnName]
{
    get
    {
        if (dictionary.ContainsKey(columnName))
            return dictionary[columnName];
        return null;
    }
    set
    {
        if (!dictionary.ContainsKey(columnName))
        {
            dictionary.Add(columnName, value);
            RaisePropertyChanged(columnName);
        }
        else
        {
            dictionary[columnName] = value;
            RaisePropertyChanged(columnName);
        }
    }
}

Now we have two alternatives to access the dynamically-created members:

// like before:
dynamic myDynamicObject2 = new DynamicDictionary();
myDynamicObject2.FirstName = "John";
myDynamicObject2.LastName = "Smith";

// using []:
var myDynamicObject3 = new DynamicDictionary();
myDynamicObject["FirstName"] = "John";
myDynamicObject["LastName"] = "Smith";

The two approaches have exactly the same effect (notice that in the second version the variable is declared with var instead of dynamic).

Using square brackets to access members has the advantage that you can actually create members using strings: let’s say you have a string/object dictionary, it’s easy to loop the dictionary entries and “create” a member for every key while setting the value as the member value. After this you’ll have an object that mirrors the dictionary:

var source = new Dictionary<string, object>();
source.Add("FirstName", "John");
source.Add("LastName", "Smith");
source.Add("Age", 18);

var target = new DynamicDictionary();
foreach (var entry in source)
    target[entry.Key] = entry.Value;

now target is the same as you would have after doing

new something() { FirstName = "John", LastName = "Smith", Age = 18 };

except that it “adapts” to any key/value you have in the dictionary. Cool eh?!

It turns out that the indexer has another side benefit (that solves the binding problem). In fact Silverlight 4 also introduced indexed bindings: you can create bindings that target indexed structures (like a list or a dictionary) simply using square brackets. The nice thing is that our dynamic class happens to have an indexer.

Let’s revisit our code: if we declare the property as DynamicDictyionary instead of dynamic (we now must set the properties using the indexer because the compiler only allows “non-existing” properties on object of dynamic type):

public DynamicDictionary MyDynamicDictionary { get; set; }

//...

MyDynamicDictionary = new DynamicDictionary();
MyDynamicDictionary["Label"] = "Hello, I'm dynamic!";

and change the XAML to look like this (notice the square brackets)

<Button Content="{Binding MyDynamicDictionary2[Label]}"/>

the dynamic binding does work fine:

okBinding

Happy dynamic binding!

Download the code

An error occurred while accessing IsolatedStorage.

While developing a Silverlight Windows Phone 7 app I ran into this problem: when the application closes, an internal  IsolatedStorageException is raised:

An error occurred while accessing IsolatedStorage.
   at System.IO.IsolatedStorage.IsolatedStorageSecurityState.EnsureState()
   at System.IO.IsolatedStorage.IsolatedStorageFile.get_AvailableFreeSpace()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.Save()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.TrySave()
   at System.IO.IsolatedStorage.IsolatedStorageSettings.SaveAllSettings()
   at MS.Internal.FrameworkCallbacks.ShutdownAllPeers()

IsolatedStorageSettings seemed to be the cause of the problem. Very weird because I wasn’t even using it! Just adding this line in my App class would cause the problem:

private System.IO.IsolatedStorage.IsolatedStorageSettings appSettings = System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings;

Now I created a new, empty, project (Windows Phone Application) and inserted that line. Weird: no problems.
I thought there was something wrong in my solution, so I made a backup copy and started removing stuff. At some point my solution was identical to the default one (except for the IsolatedStorageSettings line and the project’s GUID). Not “almost identical”, but completely, literally identical, i.e. WinMerge found no difference except the two mentioned. And of course the default solution worked while mine gave the IsolatedStorageException on shutdown.

I honestly haven’t understood the cause of the problem, but at least I’ve found a solution: change the project GUID:

  • close Visual Studio
  • open your solution’s .sln file with notepad
  • replace a couple of numbers in the Project(“{<your GUID here>}”)
  • open the .csproj with notepad
  • apply the same change to the GUID (in the first line after the comment and in all the Build Configurations)
  • Re-open your solution with Visual Studio and the problem is gone.

I suspect the problem has something to do with the emulator but I haven’t had a chance to try a real device yet. I hope I saved you an evening of head scratching.

Leaky Abstraction strikes again: FileStream.Lock() gotchas

First, if you don’t know the Law of Leaky Abstractions go on and read here (10 minutes well spent!).

.NET’s FileStream.Lock() is a handy method that lets you lock a section of a file (instead of locking it completely) so that other processes/threads cannot touch that part.

The usage is fairly simple: you specify from where to lock the file and how long is the section you want to protect. However, despite its simplicity, there are a couple of things it’s better to keep in mind or you’ll be scratching your head in front of the screen.

First: contrarily to what some articles say, this method locks part of the file for write but also for read access. Maybe those articles refer to an older framework version or whatever else, but a simple test seems to confirm that a process cannot read a part of a file that has been locked.

The second thing can be tricky.
Let’s make a simple experiment: we write 100 bytes in a new file and we lock everything except the very first byte. Then we launch another process that reads the first byte.

// first process:
using (var fs = new FileStream("myFile.txt",
                                           FileMode.Create,
                                           FileAccess.Write,
                                           FileShare.ReadWrite))
{
    using (var bw = new BinaryWriter(fs))
    {
        bw.Write(new byte[100]);
    }
    // locks everything except the first byte
    fs.Lock(1, 99);
    Console.ReadLine();
    fs.Unlock(1, 99);
}

// second process (first process is waiting at Console.ReadLine()):
using (var fs = new FileStream("myFile.txt",
                                          FileMode.Open,
                                          FileAccess.Read,
                                          FileShare.ReadWrite))
{
    using (var br = new BinaryReader(fs))
    {
        // read the first byte
        var b = br.ReadByte();
    }
}

What happens? The second process throws an exception: The process cannot access the file because another process has locked a portion of the file .
Why? We didn’t try to access the locked portion, so this should not have happened!

At first you may believe that Lock() is buggy and locks the whole file. But this is not true, in fact Lock() works correctly.
The answer is in the FileStream’s buffer (I hear the “aha!”). In fact when you ask FileStream to read a single byte, he’s smart enough not to read a single byte but to fill its internal buffer (4K by default) to speed up the reading. So it tries to read into the locked part and fails.

Now that you know why this is happening you can more or less easily solve the problem depending on your situation: you may for ex. adjust your buffer size depending on the length of the chunks you are reading.

In the example above it’s enough to pass 1 as buffer length to the second process FileStream’s constructor (after line 21) to make it work (just to show the theory, not that this is a good practice!).

I really think that the FileStream abstraction should handle this case and avoid the “leak”, but the .NET framework guys are smart people and I bet there is a good reason if it doesn’t.

Convert FILETIME to Unix timestamp

Yes I know, C/C++ is not trendy these days. I don’t care.

So if you are trying to convert a FILETIME date that comes for example from the FindFirstFile/FindNextFile Win32 API you may find it’s not completely straightforward. Don’t try to accomplish this with some date function conversion because you will probably just waste a lot of time –I know because I did.

A UNIX timestamp contains the number of seconds from Jan 1, 1970, while the FILETIME documentation says: Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).

Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds, so we will just subtract that value:

LONGLONG FileTime_to_POSIX(FILETIME ft)
{
	// takes the last modified date
	LARGE_INTEGER date, adjust;
	date.HighPart = ft.dwHighDateTime;
	date.LowPart = ft.dwLowDateTime;

	// 100-nanoseconds = milliseconds * 10000
	adjust.QuadPart = 11644473600000 * 10000;

	// removes the diff between 1970 and 1601
	date.QuadPart -= adjust.QuadPart;

	// converts back from 100-nanoseconds to seconds
	return date.QuadPart / 10000000;
}

And some code to show its usage (with various checks omitted for the sake of simplicity):

#include "stdafx.h"
#include "windows.h"

LONGLONG FileTime_to_POSIX(FILETIME ft);

int _tmain(int argc, _TCHAR* argv[])
{
	char d;
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;

	hFind = FindFirstFile(TEXT("C:\\test.txt"), &FindFileData);
	LONGLONG posix = FileTime_to_POSIX(FindFileData.ftLastWriteTime);
	FindClose(hFind);

	printf("UNIX timestamp: %ld\n", posix);
	scanf("%c", &d);

	return 0;
}