Update: Presentation slides are available on SlideShare.

Tomorrow, April 18 2012 I will speak at Toronto Architecture User Group about Acceptance Test Driven Development.

Abstract: While automated testing tools and unit testing frameworks have proven their effectiveness and are widely accepted by the agile teams practicing Test Driven Development, not many teams see a project’s test suite as the result of a joint effort between the developers, testers and domain experts. An Acceptance Test Driven Development (ATDD) approach goes one step further and brings all the stakeholders together to create an executable specification – a set of the tests written in a natural language that is understandable by the user while still being executable and verifiable. The session provides an introduction to ATDD and demonstrates the practical aspects of creating end-to-end acceptance tests, including the human side of this process. During the presentation you will also be introduced to ATDD frameworks and will learn the best practices for creating reusable and maintainable acceptance tests.

Registration at ArchitectureUG.com

My North Toronto .NET User Group Windows 8 presentation slides and samples

Samples and slides for “Getting Started with Windows 8 App Development” are available for download.

Abstract: Windows 8 represents a fundamental shift for Windows platform both in the user experience and in the development model. In this session we are going to cover the key new concepts associated with the design, development and deployment of the Windows 8 apps. We will start from an overview of Windows 8 Consumer Preview, including user experience, system architecture, execution model and the new APIs. This will be followed by a demonstration of building a Metro-style application using C# and XAML.

Deceptive simplicity of async and await

By introducing the new async/await keywords in C# 5 and by adding asynchronous APIs in .NET 4.5, Microsoft significantly lowered the bar for entering into the realm of the asynchronous programming. However, while presenting the new features of the upcoming .NET Framework release, answering the questions and helping to resolve the first issues I came to realization that this bar might be set too low.

These new additions help us to create asynchronously running methods using the familiar synchronous development model. We don’t need to segment our code to extract the parts to be executed in a separate thread or to be a callback. We don’t have to think about the threads or tasks anymore – just add await and the rest is done automatically.

That’s cool – I really like these new features and I believe they can simplify our lives, but only when used properly. Current development stack (Win7/.NET Framework 4) does not enforce the asynchronous development model. The async functionality can be introduced into existing synchronous application once the developer has fully realized the advantages of the async APIs and has mastered their proper usage.

WinRT and .NET 4.5 are different - this stack forces us to use async model. Again, this is not a bad thing but it requires some discipline and some preliminary knowledge. Right now many developers are new to the field and are experiencing the following:

Developer: “I want to use this function to read some data”
Compiler: “Good, but you may want to use await to get the string”
Developer: “OK, await is added. Can I get the string?”
Compiler: “Sure, just add async in the method header”
Developer: “Added. F5!”
Developer: “Hey, it does not work! Where is my string?”

The code looks good, it can be compiled but does not work. Why? Here are two most common mistakes I have seen so far.

Example 1

WriteFileAsync function definition:

async public void WriteFileAsync(string filename, string contents)
{
    var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
    var file = await localFolder.CreateFileAsync(filename, 
                           Windows.Storage.CreationCollisionOption.ReplaceExisting);
    var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);     
    //...
}

And this function is called as

WriteFileAsync("FileName", "Some Text");

In some cases this code will work properly. But only in some – if there is a code that depends on the file content or tries to access the same file and this code is called after WriteFileAsync(), the developer will be faced with an exception or unpredicted results.

The problem here is that the developer use awaits for the system calls but WriteFileAsync by itself is not awaitable and any code following after WriteFileAsync() call will be executed before all the expected saving operations are done. To fix the issue the method should be modified

async public Task WriteFileAsync(string filename, string contents)
{
    //...
}

And the function should be called as

await WriteFileAsync("FileName", "Some Text");

Example 2

To implement Windows 8 Sharing contract, an application should handle DataTransferManager.DataRequested event. Below you can see an example of such a handler:

async void DataRequestedHandler(DataTransferManager sender, DataRequestedEventArgs args)
{
    _fileStream = await _lastSelectedFile.OpenAsync(FileAccessMode.Read);
    
    args.Request.Data.Properties.Title = "Data Title";
    args.Request.Data.SetBitmap(_fileStream);
}

Not surprisingly, this sample does not work either. DataTransferManager does not expect that handler is asynchronous and when the await keyword returns control to the manager, the latter sees an empty data request object, assumes that the contract is not properly implemented and will not show the application on the Share panel. The fix is easy, we just need to move OpenAsync out of the method and to remove async keyword from the header, but this example demonstrates another kind of side effects – we should be very careful with the async functions when some data are expected to be returned to the external code.

These mistakes look trivial but chances are they will appear quite often due to deceptive simplicity of the new syntax. Hopefully, the next version of Visual Studio and/or ReSharper will be able to detect such situations and warn about them.

What is your opinion? Do you see a problem here?

My Metro Toronto UG presentation slides and samples

The slides and sample code from my “Windows 8 Development - Deeper Dive” presentation for Metro Toronto User Group are available for download.

The samples archive contains two demo projects:
  1. MetroDemo demonstrates file system APIs and implementation of Share, File Picker and Search contracts.
  2. TilesDemo demonstrates the basic manipulations with the application tiles.

Some comments about the MetroDemo project:

 
Is there a future for Microsoft Expression Blend for XAML?

I am not a fan of the visual designers and prefer to create UI by writing XAML code instead of dragging and dropping the controls. But from time to time I launch Expression Blend to create some animations, gradients or complex styles and I have to admit that Blend is a wonderful tool. Many developers like it. From the other side, Blend was created in the first place for the designers, not for the developers and from this point of view Blend is a failure. I have seen several attempts to teach UX experts to use Blend for sketching and designing and most of them failed. For the designers the learning curve is too steep, many features require some software development knowledge to use them properly.

During the BUILD conference Microsoft presented Expression Blend 5 Developer Preview that supports HTML only. Visual Studio 11 includes an improved XAML designer and some panels and controls that will look familiar for the Blend users but there is no any information on a standalone Blend for XAML. Taking into account that the whole BUILD event was designed to attract JavaScript/HTML developers and the preview status of the tools, I stayed calm waiting for the news. Until now.

Microsoft Advertising SDK for Windows 8 documentation includes an interesting table comparing the functionality available right now in a Preview Release with the features of a “Formal Launch”.

One row catches my eye:

Is it an answer for the question about the future of Blend for XAML or just an inaccuracy of the documentation?

On deploying ASP.NET MVC site as a desktop application

Sometimes you may find you in a situation when you have an ASP.NET web application and want to deploy it to a desktop PC. For example, for one of my projects I have the following requirements:

It is clear that such solution will be composed from 3 main components: Web application, control application (in my case it is based on .NET/WPF), Web server. And the main question is “What should I use as a server?” To satisfy the project’s requirements, the server should have the following characteristics:

 

CassiniDev

Already having an experience with CassiniDev server as a solution for the integration tests execution, I tried this one first. CassiniDev is an open-source project that includes a standalone Wev server with GUI and a library. The library, CassiniDev4-Lib.dll, contains CassiniDevServer class – an in-process Web server implementation.

_server = new CassiniDevServer();
_server.StartServer(“\\path\\to\\web\\content”));

Basically, that’s it - with two lines of code you have a server that hosts your ASP.NET application. At first look this is what is required:

But there are some cavities and probably the main one is performance. CassiniDev handles all the HTTP requests sequentially, in one thread. It is acceptable for testing but is not practical in production.

Another issue that kicks CassiniDev out of completion is an auto-shutdown after 60-seconds of idleness – it simply stops to handle any incoming requests.

IIS Express

IIS Express is a lightweight version of IIS. It runs as a separate process like full version of IIS web server, but this process is executed under the user’s account. IIS Express is a standalone application and can be started/stopped using a command line, unlike service-based full IIS.

Theoretically IIS Express is xcopy-deployable, but EULA states that IIS Express can only be redistributed using an official installer package. That means if you want to use IIS Express, it should be added as a prerequisite to your installer and will be installed as separated product.

IIS Express uses the same configuration mechanism as full IIS. Probably the easiest way to host the site on IIE Express, is to create own applicationhost.config, deploy it on the target system and use it to start the server:

"C:\Program Files\IIS Express\iisexpress.exe" /config:D:\Fileversum\config\applicationhost.config

Even IIS Express is installed into the system it will not be started automatically on the Windows start. You have to do it by yourself by creating some kind of launcher or incorporating this functionality into the control application, to be able to start/stop the server on-demand.

By default IIS Express does not require elevated permissions, but in the same time it default configuration does not support network requests and port 80. You need the administrative privileges to unlock these features. The post by Scott Hanselman describes the required manipulations, but in short you need to do the following:

Note that netsh does not exist in Windows XP and httpcfg should be used instead. That means an additional complexity for the installation script.

UltiDev Web Server Pro

UltiDev Web Server Pro is a successor for UltiDev Cassini Web Server, a freeware redistributable Web server. The product is relatively new, but it is in active development and demonstrates a good stability, performance and a reach feature set.

Like IIS Express, UWS is a standalone out-of-process Web server. It runs as a service, includes GUI frontend but also provides an API and the command line tools. UltiDev Server cannot be privately deployed, you have to install it. Fortunately the server redistributable packages for InstallShield, Advanced Installer and VS bootstrapper are available.

If you prefer to register your site during the installation, UWS provides a command line utility that can be used for this propose. If you need more control under the site’s lifecycle, a .NET-based API exposed from UWS.Configuration.dll library might be an option. Below you can see a sample code demonstrating site registration:

var app = Metabase.GetWebAppEntry(ApplicationGUID, false);
app.VirtualDirectory = "/Fileversum";
app.PhysicalDirectory = “\\path\\to\\web\\content”;
app.ApplicationName = "Fileversum";
app.AppType = ApplicationType.AspNetOrStaticHtml;
app.ListenAddresses.AddRange(new[] { new ListenAddress(80) });

Metabase.RegisterApplication(RuntimeVersion.AspNet_4, true, app);

And un-registration:

Metabase.UnregisterApplication(ApplicationGUID);

Both operations (registration and un-registration) require the administrative rights. So if this code is incorporated into the control application, it must be able to request the elevated partitions.

As soon as the site is registered, it will be available for the local and the network users. No additional actions are required to start the server or site after Windows reboot.

Additionally, to simplify the site deployment, UWS supports auto detection of the available ports.

My CTTDNUG presentation slides and samples

I published the slides and sample code from my presentation about Windows 8 at Canada’s Technology Triangle .NET User Group meeting. The slides are also available on Slideshare.

Feel free to contact me if you want to discuss them.

WinRT and Windows Property System part 2: searching for files by metadata

The functions provided by WinRT to store and read files metadata are useful when you want to help your users with the files categorization. But what is even more interesting, you can use the saved properties to search for files.

For example, you can use the following code to get all the photos taken using Pentax camera and saved as .jpg files into the Pictures library:

var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, new[] { ".jpg" });
queryOptions.FolderDepth = FolderDepth.Deep;
queryOptions.ApplicationSearchFilter = "cameramake:pentax";

StorageFileQueryResult query = 
          KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);

IReadOnlyList files = await query.GetFilesAsync();
foreach (var file in files)
{
   Debug.WriteLine(file.FileName);
}

ApplicationSearchFilter is an Advanced Query Syntax string and is optional. If it is not defined the query will simply return all .jpg files.

The first parameter in the QueryOptions constructor defines type of the query. Using this parameter you can control the search depth and the sorting method. CommonFileQuery.DefaultQuery means shallow search – the query engine will not search for the files in the subfolders of the target folder. This behavior can be altered by assigning FolderDepth.Deep value to QueryOptions.FolderDepth property.

All the ordered queries (OrderByTitle, OrderByDate, etc.) use the deep search by default and return the flat list of all the matched files or folders in all the subfolders. But what is equally important, these queries use different methods for retrieving the results. Let’s see the following queries:

var queryOptions = new QueryOptions(CommonFileQuery.DefaultQuery, new[] { ".jpg" });
queryOptions.FolderDepth = FolderDepth.Deep;
var query = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList files = await query.GetFilesAsync();
var queryOptions = new QueryOptions(CommonFileQuery.OrderByDate, new[] { ".jpg" });
var query = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList files = await query.GetFilesAsync();

In theory, both queries should return the same number of the files. But when I tested this code on my system, the first query returned 24 files and the second – just 3 files.

This happened because all the ordered queries use index database to search for the files while the default query inspects the file system to find the matches. On my system the index was somehow corrupted and the query was not able to get all the files. Rebuilding the index solved the issue – both queries returned the same number of files.

Using the index database for the search helps to reduce search time and resources usage – even such a simple query was 1.5 times faster in the indexed mode - but it might be a good idea to use the default mode for the critical queries, to be sure that you received a complete view.

It is very likely that the StorageFile objects returned by the queries will be used to extract metadata and generate thumbnail for presenting to the user. As this scenario is very common, WinRT provides a class that combines all these actions together:

var queryOptions = new QueryOptions(CommonFileQuery.OrderByDate, new[] { ".jpg" });
var query = KnownFolders.PicturesLibrary.CreateFileQueryWithOptions(queryOptions);

var fileInfoFactory = new FileInformationFactory(query, ThumbnailMode.PicturesView);
IReadOnlyList fileInfoList = await fileInfoFactory.GetFilesAsync();
            
foreach (FileInformation fileInfo in fileInfoList)
{
   Debug.WriteLine(fileInfo.FileName);

   ImageProperties properties = fileInfo.ImageProperties;
   properties.Keywords.Add("new");
   await properties.SavePropertiesAsync();
}

FileInformation class implements IStorageItem and IStorageFile interfaces and therefore can be used to read and write, copy or delete the file. Additionally it implements IStorageItemInformation to synchronously provide file’s thumbnail and properties.

Nothing comes for free – FileInformationFactory queries are about 3 times slower that the simple indexed queries executed with the same options. The additional time is required to extract the properties and create the thumbnails – so if you don’t need all these information, the simple query will be a better option.

WinRT and Windows Property System part 1: storing and retrieving files metadata

Windows Property System, introduced in Windows Vista, provides you a uniform mechanism to access Shell items’ metadata. Using WPS you can store and retrieve properties of the items such as folders, files, contacts or emails.

WinRT provides a straightforward method of accessing the most frequently used properties grouped by the file type (Image, Music, Video, etc.) as well as a method of accessing the individual properties.

The following code sample demonstrates how to retrieve image file properties, modify one of them and store it back to the file:

...
var file = await someFolder.GetFileAsync("IMGP8648.JPG");
var fileProperties = await file.Properties.GetImagePropertiesAsync();

fileProperties.Rating = 25;

await fileProperties.SavePropertiesAsync();

Using the same approach you can work with the document, music, video and basic (size, date modified) file properties. An interesting point here that you are able to call GetMusicPropertiesAsync() for a document file and it will return an empty MusicProperties object. But if you will try to change this object and save it back, an exception will be thrown – “Value does not fall within the expected range”. The helper classes do not expose all the available properties. To access the rest of them, you will need to know canonical names for these properties and need to use RetrievePropertiesAsync() function:

var fileProperties = await file.Properties.RetrievePropertiesAsync(
           new List { "System.GPS.Latitude", "System.GPS.Longitude" });

var latitude = fileProperties["System.GPS.Latitude"];

To modify an extended property you need to provide a pair of the property name and the new property value:

var propertyToSave = new List> 
       { new KeyValuePair("System.Photo.LensManufacturer", "Pentax") };

await file.Properties.SavePropertiesAsync(propertyToSave);

Also there is a possibility to get all the properties associated with the file by providing an empty list of the properties to retrieve:

...
var fileProperties = await file.Properties.RetrievePropertiesAsync(new List {});
...

RetrievePropertiesAsync() returns an object of IMap<String, Object> where the first parameter is a property identifier and the second is a value. Below you can see an example of the results returned by this function:

Key: {B725F130-47EF-101A-A5F1-02608C9EEBAC} 14
Value: 13/10/2011 12:02:10 AM -04:00
Key: {6336B95E-C7A7-426D-86FD-7AE3D39C84B4} 100
Value: Auto
Key: {14B81DA1-0135-4D31-96D9-6CBFC9671A99} 272
Value: PENTAX K10D
Key: {14B81DA1-0135-4D31-96D9-6CBFC9671A99} 33434
Value: 0.0005

At first look this is not very informative, right? But if we will check MSDN, we can find that keys consist of the two parts – format ID (GUID) and property ID (number) and all these IDs are described as part of the property schema. For example, the first value - {B725F130-47EF-101A-A5F1-02608C9EEBAC} 14 - represents a date and time of the last write to the file, the last value - {14B81DA1-0135-4D31-96D9-6CBFC9671A99} 33434 – represents the photo expose time.

So this information is not useless, but I hope to see in the future some sort of helpers to convert property IDs into the canonical names such as System.DateModified or System.Photo.ExposureTime.

Exploring WinRT: Storage.AccessCache

Exploring WinRT:

1. Windows.Storage namespace overview
2. File and Folder Pickers
3. Storage.AccessCache

Let’s imagine that we are creating a Metro style text editor. With help of the pickers users are able to open and save files at any location. But what if the user wants to reopen a file he or she edited last week? Do we need to show the picker and ask him to open file again? It will be nice to have a list of the recently used documents and provide a way to reopen them with one click.

Fortunately, WinRT architects thought about this scenario and introduced several classes grouped together within Windows.Storage.AccessCache namespace:

...
StorageFile file = await filePicker.PickSingleFileAsync();
string token = StorageApplicationPermissions.FutureAccessList.Add(file, “metadata”);

If you have an object of StorageFile or StorageFolder type and you want to keep it accessible, class StorageItemAccessList provides you a way. Method Add() will add your file system object to the list and return a string token (GUID) that can be used in the future to get the object back. All the added objects stay accessible even after application restart and can be easily retrieved without interacting with the user:

if (StorageApplicationPermissions.FutureAccessList.ContainsItem(folderID))
{
   StorageFolder folder = 
         await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(folderID);
   ...
}

where StorageApplicationPermissions is a static class declared in Windows.Storage.AccessCache.

If you want to provide your own token, there is an alternative to Add() method:

StorageApplicationPermissions.FutureAccessList.AddOrReplace(“LastUsedFile”, file, “metadata”);

This method adds a new item to the access list, or replaces the specified item if it already exists in the list. The last parameter for both Add() and AddOrReplece() is an optional metadata to associate and store with the file system object. There is no special methods to access the metadata, it is only accessible through Entries collection:

...
AccessListEntry item = StorageApplicationPermissions.MostRecentlyUsedList.Entries[n];
string metadata = item.Metadata;
...

The same tokens are used to remove the items from the access list, using Remove(). Or you can use Clear() method to wipe out the list completely. These methods are important because the list is not boundless – the maximum number of the items in the list is indicated by MaximumItemsAllowed and for me it is equal to 25. Yes, just 25 items can be saved simultaneously, so goodbye an idea to track all the files ever used.

It is very common situation, when your app is trying to open a previously used file but the file does not exist because it is already renamed or moved. Good news: FutureAccessList tracks this situation automatically. Even if the file or folder moved, it is still associated with the same token and will be returned to you when you need it.

In addition to FutureAccessList, StorageApplicationPermissions includes MostRecentlyUsedList property of StorageItemMostRecentlyUsedList class. This is an independent list that implements the same functionality as FutureAccessList and can keeps up to 25 storage items. The only difference is an ItemRemoved event, implemented by StorageItemMostRecentlyUsedList, but I was not able to trigger it – Remove() and Clear() do not fire this event. It is not clear why do we need both classes and my best guess that MRU list will be used by system somehow, but in the Developer Preview version these interactions are not implemented yet.

Next posts Previous posts