Running Azure emulators in on-site test environment

The Azure compute and storage emulators enable testing and debugging of Azure cloud services on the developer’s local computer. On my current project, I ran into the need to install and run the emulator in the test environment. I will not go into exactly why this was needed, but it could be a possible interim solution to try out the technology before your customer make the decision to establish an environment in Azure. There were quite a few hurdles in the way to do this. I try to summarize them all in this post.

So the basic setup that I will explain in this blog post is to build a package for deployment in the compute emulator on the Team City build server. We will do the deployment using Octopus Deploy:

+-------------+   +--------------+   +---------------+   +---------+----------+
|             |   |              |   |               |   |  Test environment  |
| Dev machine +---> Build server +---> Deploy server +---> (Compute emulator) |
|             |   | (Team City)  |   | (Octopus)     |   | (Storage emulator) |
|             |   |              |   |               |   |                    |
+-------------+   +--------------+   +---------------+   +--------------------+

Preparing the test environment

This step consists of preparing the test environment for running the emulators.

Installing the SDK

First of all, let’s install the necessary software. I used the currently (September 2014) latest version of the Microsoft Azure SDK, version 2.4. This is available in the Microsoft web platform installer (http://www.microsoft.com/web/downloads/platform.aspx):
Azure SDK 2.4 in Web Platform installer
Take note of the installation paths for the emulators. You’ll need them later on:

Compute emulator: C:\Program Files\Microsoft SDKs\Azure\Emulator
Storage emulator: C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator

Create a user for the emulator

The first problem I ran into was concerning which user should run the deployment scripts. In a development setting, this is currently logged in user on the computer, but in a test environment case, this is not so.

I decided to create a domain managed service account named “octopussy” for this. (You know, that James Bond movie.) Then, I made sure that that user was a local admin on the test machine by running

net localgroup administrators domain1\octopussy /add

In order for the Octopus Deploy tentacle to be able to run the deployment, the tentacle service must run as the aforementioned user account:
Setting user for Octopus Tentacle service

Creating windows services for storage and compute emulators

In a normal development situation, the emulator run as the logged in user. If you remotely log in to a computer and start the emulators, they will shut down when you log off. In a test environment, we need the emulators to keep running. Therefore, you should set them up to run as services. There are several ways to do this, and I choose to use the Non-sucking service manager.

First, create a command file that starts the emulator and never quits:

storage_service.cmd:

@echo off
"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\WAStorageEmulator.exe" start
pause

devfabric_service.cmd:

@echo off
"C:\Program Files\Microsoft SDKs\Azure\Emulator\csrun.exe" /devfabric
pause

Once the commands files are in place, define and start the services:

.\nssm.exe install az_storage C:\app\storage_service.cmd
.\nssm.exe set az_storage ObjectName 'domain1\octopussy' 'PWD'
.\nssm.exe set az_storage Start service_auto_start
start-service az_storage
.\nssm.exe install az_fabric C:\app\devfabric_service.cmd
.\nssm.exe set az_fabric ObjectName 'domain1\octopussy' 'PWD'
.\nssm.exe set az_fabric Start service_auto_start
start-service az_fabric

Change the storage endpoints

In a test environment, you would often like to access the storage emulator from remote machines, for instance for running integration tests. Again, being focused on local development, the storage emulator is only accessible on localhost. To fix this, you need to edit the file

C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\WAStorageEmulator.exe.config

Per default, the settings for the endpoints are like so:

<services>
    <service name="Blob"  url="http://127.0.0.1:10000/" />
    <service name="Queue" url="http://127.0.0.1:10001/" />
    <service name="Table" url="http://127.0.0.1:10002/" />
</services>

The 127.0.0.1 host references should be change to the host’s IP address or NetBIOS name. This can easily be found using ipconfig. For example:

<services>
    <service name="Blob"  url="http://192.168.0.2:10000/" />
    <service name="Queue" url="http://192.168.0.2:10001/" />
    <service name="Table" url="http://192.168.0.2:10002/" />
</services>

I found this trick here.

What we can do now, is to reach the storage emulator endpoints from a remote client. To do this, we need to set the DevelopmentStorageProxyUri parameter in the connection string, like so:

UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://192.168.0.2

In some circumstances, for instance if accessing the storage services using Visual Studio server explorer, you cannot use the UseDevelopmentStorage parameter in the connection string. Then you need to format the connection string like this:

BlobEndpoint=http://192.168.0.2:10000/;QueueEndpoint=http://192.168.0.2:10002/;TableEndpoint=http://192.168.0.2:10001/;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

Open endpoints in firewall

If you run your test environment on a server flavor of Windows, you might have to open up the storage emulator TCP ports in the firewall:

netsh advfirewall firewall add rule name=storage_blob  dir=in action=allow protocol=tcp localport=10000
netsh advfirewall firewall add rule name=storage_queue dir=in action=allow protocol=tcp localport=10001
netsh advfirewall firewall add rule name=storage_table dir=in action=allow protocol=tcp localport=10002

Create a package for emulator deployment

So, now that we have the test environment set with the Azure emulators, let’s prepare our application for build and deployment. My example application consists of one Worker role:

Solution with Worker Role

One challenge here is that if you build the cloud project for the emulator, no real “package” is created. The files are laid out as a directory structure to be picked up locally by the emulator. The package built for the real McCoy is not compatible with the emulator. Also, in order to deploy the code using Octopus Deploy, we need to wrap it as a Nuget package. The OctoPack tool is the natural choice for such a task, but it does not support the cloud project type.

Console project as ‘wrapper’

To fix the problem with creating a Nuget package for deployment to the emulator, we create a console project to act as a “wrapper.” We have no interest in a console application per se, but only in the project as a vehicle to create a Nuget package. So, we add a console project to our solution:

Added wrapper project to solution

We have to make sure that the WorkerRole project is built before our wrapper project, so we make sure the build order in the solution is correct:

Build order

Customizing the build

What we want, is the build to perform the following steps:

  1. Build WorkerRole dll
  2. Build Worker (cloud project) – prepare files for the compute emulator
  3. Build Worker.Wrapper – package compute emulator files and deployment script into a Nuget package

We have the two steps already covered with the existing setup. So what we need to do in the third step is to copy the prepared files to the build output directory of the Wrapper project, and then have OctoPack pick them up from there.

To copy the files, we set up a custom build step in the Wrapper project:

<PropertyGroup>
    <BuildDependsOn>
    CopyCsxFiles;
    $(BuildDependsOn);
  </BuildDependsOn>
  </PropertyGroup>
  <PropertyGroup>
    <CsxDirectory>$(MSBuildProjectDirectory)\..\Worker\csx\$(Configuration)</CsxDirectory>
  </PropertyGroup>
  <Target Name="CopyCsxFiles">
    <CreateItem Include="$(CsxDirectory)\**\*.*">
      <Output TaskParameter="Include" ItemName="CsxFilesToCopy" />
    </CreateItem>
    <ItemGroup>
      <CsConfigFile Include="$(MSBuildProjectDirectory)\..\Worker\ServiceConfiguration.Cloud.cscfg" />
    </ItemGroup>
    <Copy SourceFiles="@(CsxFilesToCopy)" DestinationFiles="@(CsxFilesToCopy->'$(OutDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
    <Copy SourceFiles="@(CsConfigFile)" DestinationFolder="$(OutDir)" />
  </Target>

We copy all the files in the csx directory in addition to the cloud project configuration file.

The next step is then to install OctoPack in the Wrapper project. This is done using the package manager console:

Install-Package OctoPack -ProjectName Worker.Wrapper

We’re almost set. Like I said earlier, the Wrapper project is a console project, but we are not really interested in a console application. So in order to remove all unnecessary gunk from our deployment package, we specify a .nuspec file where we explicitly list the files we need in the package. The .nuspec file name is prefixed with the project name. In this case, Worker.Wrapper.nuspec, and it contains:

<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <files>
    <file src="bin\release\roles\**\*.*" target="roles" />
    <file src="bin\release\Service*" target="." />
    <file src="PostDeploy.ps1" target="." />
    <file src="PreDeploy.ps1" target="." />
  </files>
</package>

We can now create a deployment package from msbuild, and set for build this artifact on Team City:

msbuild WorkerExample.sln /p:RunOctoPack=true /p:Configuration=Release /p:PackageForComputeEmulator=true
dir Worker.Wrapper\bin\release\*.nupkg

Notice that we set the property PackageForComputeEmulator to true. If not, Msbuild will package for the real Azure compute service in release configuration.

Deployment scripts

The final step is to deploy the application. Using Octopus Deploy, this is quite simple. Octopus has a convention where you can add PowerShell scripts to be executed before and after the deployment. The deployment of a console app using Octopus Deploy consists of unpacking the package on the target server. In our situation we need to tell the emulator to pick up and deploy the application files afterwards.

In order to finish up the deployment step, we create one file PreDeploy.ps1 that is executed before the package is unzipped, and one file PostDeploy.ps1 to be run afterwards.

PreDeploy.ps1

In this step, we make sure that the emulators are running, and remove any existing deployment in the emulator:

$computeEmulator = "${env:ProgramFiles}\Microsoft SDKs\Azure\Emulator\csrun.exe"
$storageEmulator = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\Storage Emulator\WAStorageEmulator.exe"

$ErrorActionPreference = 'continue'
Write-host "Starting the storage emulator, $storageEmulator start"
& $storageEmulator start 2>&1 | out-null

$ErrorActionPreference = 'stop'
Write-host "Checking if compute emulator is running"
& $computeEmulator /status 2>&1 | out-null
if (!$?) {
    Write-host "Compute emulator is not running. Starting..."
    & $computeEmulator /devfabric:start
} 

Write-host "Removing existing deployments, running $computeEmulator /removeall"
& $computeEmulator /removeall

PostDeploy.ps1

In this step, we do the deployment of the new application files to the emulator:

$here = split-path $script:MyInvocation.MyCommand.Path
$computeEmulator = "${env:ProgramFiles}\Microsoft SDKs\Azure\Emulator\csrun.exe"

$ErrorActionPreference = 'stop'
$configFile = join-path $here 'ServiceConfiguration.Cloud.cscfg'

Write-host "Deploying to the compute emulator $computeEmulator $here $configFile"
& $computeEmulator $here $configFile

And with that, we are done.

Moving my blog to Azure Web Sites

This blog has ran on a dedicated WordPress installation hosted by domeneshop.no. A couple of weeks ago, I decided to move my blog to Azure Web Sites. There were many reasons for this, all of them evolving around me wanting to investigate the technology and the offerings in Microsoft Azure in general, and in Web Sites in particular. Here’s how it went.

Creating the new site

The first step was obviously to create the new Web site in Azure. This turned out being very simple. I used the first part of Dave Bost’s blog series on Moving a WordPress Blog to Windows Azure for guidance. It all went easy peasy.

Moving the content

When Wordpess had been installed, the next step was to move the content. This step was a bit troublesome, and I had to try this I few times before making it work. I tried Dave’s approach in Moving a WordPress Blog to Windows Azure – Part 2, but it did not work our quite well for me. First of all, the “Portable phpMyAdmin” admin had evolved into “Adminer”, and a few of the features seems to have been changed on the way.

I ended up with first copying the content of the wp-content/uploads directory using FTP. Using FileZilla as a client, all I needed to do, was to reset my deployment credentials for the web site in Azure. I was then able to log in using FTP. (I were not able to make SFTP work, though.)

I then reinstalled the themes and plugins on the new site manually. After all, this was a good opportunity to clean up anyways, leaving the dated, not used, plugins and themes behind.

Finally, I moved the blog posts using the build in export and import functionality in WordPress.

Changing URLs

My intention as to host the www.kongsli.net address using my newly installed site at http://musings.azurewebsites.net. One tiny detail regarding URLs was that on my old site, the WordPress installation was in the subdirectory /nblog. On my new site, the WordPress installation was in the root directory. So I needed to forward requests to /nblog/* to /*. My first idea was to use IIS Rewrites for this, but according to this Stackoverflow question this module is not installed in Azure web sites. Instead, I then went on to creating an extremely simple ASP.NET MVC app to do the redirection. (Yes, I could probably have pulled this off using Web API as well, but MVC is more familiar to me)

Here is the essential code:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        var queryString = Request.QueryString.ToString();
        var location = "/" + id + (string.IsNullOrEmpty(queryString) ? string.Empty : "?" + queryString);
        return new RedirectResult(location, true);
    }
}

The trick I wanted to use, then, is to install this application in IIS under /nblog so that it will handle all requests to /nblog/*. To do this, I needed to use the FTP method for publishing the app to Azure:

Publish using FTP

Notice that the site path is set to site/nblog-redirector, which will locate it “beside” the WordPress installation at site/wwwroot on the server. Then, the application can be set up in the Azure Management
portal:

Applications and virtual directories

As you can see from the picture above, I also had to take care of some other content besides my blog, that I could FTP to the new site and register as virtual directories in IIS. Pretty nifty.

Using a custom domain

I wanted to host www.kongsli.net using my new web site in Azure. There were essentially two steps needed for this, only one of which that was apparent to me at the time. The apparent one was that I needed a DNS record that pointed www.kongsli.net to the web site. The existing record was an A record that pointed www.kongsli.net to my current hosting provider’s infrastructure. Because of the scalable, high availability nature of Azure web sites, this needed to be replaced by a CNAME record pointing www.kongsli.net to musings.azurewebsites.net. This as easy to set up at my current DNS provider:

dns_records_domeneshop

Once set up, all there was to do, was to wait for the DNS change to propagate. At least, so I thought. The final piece of the puzzle, was that the custom domain name to be hosted in the Azure web site needed to be registered. There might be more to it, but I guess that the web sites uses host headers to distinguish requests in shared hosting scenarios in Azure web sites. I also found that in order to add custom domain names, I needed to change my hosting plan from “Free” to at least “shared”. When I did, I could register my domain:

Setting up custom domain names in web sites

And voilá.

Hello, Azure Scheduler

The Scheduler is one of the new kids on the block in Azure Land. With Scheduler you can set up triggers for some sort of event in your system. It is currently in preview. I took some time to get to know the basics of it, and I wrote up a three part series of articles. You can find the articles in my company’s blog:

Handling nullables efficiently

I earlier wrote about Handling null checks efficiently by using extension methods to make our code more terse, not cluttered by null check blocks. When we use nullables (Nullable<T>), we come across a similar construction in our code. We have to check if the nullable has a value before accessing the value. If we try to reference the value of a nullable, and it has no value, we get an InvalidOperationException. This is quite similar to getting an NullReferenceException if trying to access a reference which is null.

Let’s take the example code from my previous post, and add an enum for Nationality. Then, we add a Citizenship property with type Nullable<Nationality> to the Person class. Like so:

enum Nationality
{
    No,Se,Dk,Uk,Us
}
internal class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public Nationality? Citizenship { get; set; }
}

If we then create a Person object that has the Citizenship property not set, we get an exception if we try to dereference it:

var person = new Person {Name = "Jackie Chiles"};
Console.Write("Citizenship:");
Console.Write(person.Citizenship.Value);

Handling nullables efficiently

What we can do here, is that we can create an .IfHasValue and .DoIfHasValue extension methods that are analogous to the .IfNotNull and .DoIfNotNull extension methods in the previous blog post:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static void DoIfHasValue<T>(this T? obj, 
        Action<T> action, bool doContinue = true) where T : struct
    {
        if (obj.HasValue)
        {
            action(obj.Value);
        }
        if (doContinue)
            return;
        ThrowInvalidOperationException<T, T>();
    }
    [DebuggerStepThrough]
    public static TResult IfHasValue<T, TResult>(this T? obj, 
        Func<T, TResult> func, bool doContinue = true, 
        TResult defaultValue = default(TResult)) where T : struct
    {
        if (obj.HasValue)
        {
            return func(obj.Value);
        }
        return doContinue ? defaultValue : 
            ThrowInvalidOperationException<T, TResult>();
    }
    [DebuggerStepThrough]
    private static TResult ThrowInvalidOperationException<T, TResult>()
    {
        throw new InvalidOperationException(string.Format(
            "Tried to access value of nullable of {0}, but it had no value",
                typeof(T).FullName));
    }
}

Now we can use this to prevent our code from throwing an exception, and return a default value instead:

 var person = new Person {Name = "Jackie Chiles" };
 Console.Write("Citizenship:");
 Console.Write(person.Citizenship.IfHasValue(c => c.ToString()));

If we wish to give it another default value, we can simply do this like so:

Console.Write(person.Citizenship
    .IfHasValue(c => c.ToString(), defaultValue: "(unknown)"));

You can find the code on GitHub

Handling null checks efficiently

At the QCon Conference in London in 2009, Sir C.A.R. Hoare apologized for inventing the null reference back in 1965 for the Algol W programming language. He called it his billion-dollar mistake.

Checking for null is one of the constructs that we use very often in our C# code. If we have a lot of them, they tend to clutter our code and make it harder to read and understand the business logic that our code implements. In this post I will use extension methods to make a bit more terse null checks to handle a few different code cases. It is by no means a novel idea, you can find various references on the web. Anyway, let’s give it a try.

Let’s consider this simple object model:

    +--------+    +-----------------+
    | Person |    | Address         |
    |--------|+-->|-----------------|
    | Name   |    | City            |
    +--------+    | PostalCode      |
                  | Street          |
                  | WriteToConsole()|
                  | ToString()      |
                  +-----------------+

We have a Person class which contains a reference to an Address class. When our program are trying to reference properies of the Address objects via the Person object, we have to consider that the reference to the Address object might be null. Here’s an example of what we would start out with:

var person = new Person {Name = "Cosmo Kramer"};
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
person.Address.WriteToConsole();

Of course, if person.Address is null, this will give us a NullReferenceExecption. So, one way to handle this, is to check for null before calling WriteToConsole, like so:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
if (person.Address != null)
{
    person.Address.WriteToConsole();
}

This is good, but if we have a lot of such null checks like these, our code will be quite cluttered. One simple solution would be to create an extension method that let us give a code to be called if the object called on is not null. Consider the following method:

public static class FlowControlExtensions
{
    public static void DoIfNotNull<T>(this T obj,
        Action<T> action) where T : class
    {
        if (obj != null)
        {
            action(obj);
        }
    }
}

If we use this new method, our code now looks like this:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
person.Address.DoIfNotNull(a => a.WriteToConsole());

Then we have a little more terse code. In this example, the execution will continue if the Address property of the person object is null. In some situations, nulls are not acceptable and we would like to throw an exception. For example:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
if (person.Address != null)
{
	person.Address.WriteToConsole();
}
else
{
	throw new NullReferenceException();
}

One of the annoying things about the standard .NET usage of the NullReferenceException is that it’s error message does not contain any hints about which object was null. Let’s take the opportunity to make it little better. Let’s change our DoIfNotNull method implementation:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static void DoIfNotNull<T>(this T obj,
        Action<T> action, bool doContinue = true) where T : class
    {
        if (obj != null)
        {
            action(obj);
        }
        if (doContinue) return;
        throw new NullReferenceException(
            string.Format("Reference of type {0} was null.",
                typeof (T).FullName));
    }
}

We have added a default parameter to the method signature. This acts as a flag to set whether or not to continue the execution if null occurs, or throw an exception. Also, we take care to construct the error message so that it gives us the type of the reference being null, which would help us a bit investigating the error. Also note that I added the DebuggerStepThroughAttribute which means that the debugger will not step into this method, so that it will actually stop at the same code line as it would before we introduced our extension method. In the situation that we wish to throw an exception if the reference is null, the example now looks like so:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
person.Address.DoIfNotNull(a => a.WriteToConsole(), doContinue : false);

This code will now throw an exception with the message “Reference of type Address was null.”

So, now we have the possibility to run any code snippet that fits in an Action<T> if the reference is not null. Let’s try to handle the situation where we wish to evaluate an expression instead. Consider the following example:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
Console.WriteLine(person.Address.ToString());

The last line in this example will throw a NullReferenceException if the Address property is not set. Again, we will try to handle this situation using an extension method:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static TResult IfNotNull<T,TResult>(this T obj, 
        Func<T, TResult> func) where T : class
    {
        if (obj != null)
        {
            return func(obj);
        }
        return default(TResult);
    }
}

Notice that if the object reference in fact is null, we return default(TResult) from the extension method. Now, we achieve to make our code run even though we have a null reference:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
Console.WriteLine(person.Address.IfNotNull(a => a.ToString()));

One improvement we might want to do here, is to make our little program make it explicit if the address is null. Right now, it will only print a blank line. Let’s make a small change to our extension method:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static TResult IfNotNull<T,TResult>(this T obj,
        Func<T, TResult> func, 
        TResult defaultValue = default(TResult)) where T : class
    {
        if (obj != null)
        {
            return func(obj);
        }
        return defaultValue;
    }
}        

Here we introduced a named parameter which by default is default(TResult). If we wish, we can now override this to give the value returned by the extension method in case of null:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
Console.WriteLine(person.Address.IfNotNull(a => a.ToString(), defaultValue : "(unknown)"));

Before we call it a day, let’s handle one final scenario. Say that we actually want to sustain the default behavior in case of null, throw a NullReferenceException. This is trivial to do, but let’s take the opportunity to give a more helpful error message than the one we get by default. For this, we will put expression trees to work.

Instead of having our extension method take a Func<T,TResult> parameter, we will make it an Expression<Func<T,Result>>. What we achieve with this is to be able to traverese the expression tree to look for the property or method on the reference being null that we were trying to call. This will give us helpful hints about which object reference was actually null. Also, let’s introduce a parameter that enables us to say that we wish to throw an exception in case of an error. A simple implementation looks like this:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static TResult IfNotNull<T,TResult>(this T obj, 
        Expression<Func<T, TResult>> func, 
        TResult defaultValue = default(TResult), 
        bool doContinue = true) where T : class
    {
        if (obj != null)
        {
            return func.Compile()(obj);
        }
        if (doContinue) return defaultValue;
        throw new NullReferenceException(
            string.Format("Reference of type {0} was null.",
                typeof (T).FullName));
    }
}

We can now use this method to throw an exception in case of null:

var person = new Person { Name = "Cosmo Kramer" };
Console.WriteLine("Person: {0}", person.Name);
Console.WriteLine("Address:");
Console.WriteLine(person.Address.IfNotNull(a => a.ToString(), doContinue: false));

If the Address property is null, it will throw a NullReferenceException with the message ‘Reference of type Address was null.’.

Handling null checks efficiently-2

Let’s try to see if we can improve the error message to give us a little more information. First, let’s introduce a private class which will traverse the expression tree to look for the method or property referenced:

public static class FlowControlExtensions
{
    private class MemberNameCollector : ExpressionVisitor
    {
        public string MemberName = "Unknown";
        private readonly string _parameterName;
        public MemberNameCollector(string parameterName)
        {
            _parameterName = parameterName;
        }
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Object != null 
                && node.Object.NodeType == ExpressionType.Parameter
                && _parameterName == node.Object.ToString())
            {
                MemberName = node.Method.Name + "(...)";
            }
            return base.VisitMethodCall(node);
        }
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.NodeType == ExpressionType.MemberAccess 
                && node.Expression.ToString() == _parameterName)
            {
                MemberName = node.Member.Name;
            }
            return base.VisitMember(node);
        }
    }
}

We can now use this class to alter the implementation of our IfNotNull extension method:

public static class FlowControlExtensions
{
    [DebuggerStepThrough]
    public static TResult IfNotNull<T,TResult>(this T obj,
        Expression<Func&ltT, TResult>> func, 
        TResult defaultValue = default(TResult), 
        bool doContinue = true) where T : class
    {
        if (obj != null)
        {
            return func.Compile()(obj);
        }
        if (doContinue) return defaultValue;
        var parameterName = func.Parameters.First().Name;
        var parameterType = typeof (T).FullName;
        var visitor = new MemberNameCollector(parameterName);
        visitor.Visit(func.Body);
        throw new NullReferenceException(
            string.Format("Tried to reference .{0} on parameter with name '{1}' of type {2}, but it was  null",
            visitor.MemberName, parameterName, parameterType));
    } 
}

We now get a little more information in our NullReferenceException message stating “Tried to reference .ToString(…) on parameter with name ‘a’ of type Address, but it was null”. A little more helpful…

Handling null checks efficiently-3

Summary

We have used extension methods to handle several null handling situations in a terse way. Here’s what we have covered:

person.Address.DoIfNotNull(a => a.WriteToConsole()); Runs a statement. Continue execution in case of null.
person.Address.DoIfNotNull(a => a.WriteToConsole(), doContinue : false); Runs a statement. Throws a NullReferenceException in case of null. Somewhat improved exception message compared to OOTB.
person.Address.IfNotNull(a => a.ToString()); Evaluates an expression. Returns default(T) in case of null.
person.Address.IfNotNull(a => a.ToString(), defaultValue : "(unknown)"); Evaluates an expression. Returns "(unknown)" in case of null.
person.Address.IfNotNull(a => a.ToString(), doContinue: false); Evaluates an expression. Throws a NullReferenceException in case of null. Improved exception message compared to OOTB.

If you want to try this out yourself, it is quite straightforward to copy and paste the code. You can also find the example code on GitHub.

Powershell gotchas: refer to variables outside a function

Consider the following code:

$x = 1
function changeit {
    "Changing `$x. Was: $x"
    $x = 2
    "New value: $x"
}
"`$x has value $x"
changeit
"`$x has value $x"

Not too complicated, right. Let’s see what happens when we run it:

$x has value 1
Changing $x. Was: 1
New value: 2
$x has value 1

What’s going on? Well, trying to change the value of $x inside the function did not work. Why not? What the statement $x = 2 actually does, is to create a local variable inside the function and give it the value of 2. Let’s fix that:

$x = 1
function changeit {
    "Changing `$x. Was: $x"
    $script:x = 2
    "New value: $x"
}
"`$x has value $x"
changeit
"`$x has value $x"

Now, we run it again:

$x has value 1
Changing $x. Was: 1
New value: 2
$x has value 2

The thing is that we have to explicitly tell Powershell to update the variable in the parent scope instead of creating a new variable in the current scope.

Windows 8 Store: må ha en-US i listen av språk på maskinen

(This post is in Norwegian. For a short English summary, scroll to the bottom of the post)

Når du installerer Windows 8, er det viktig at du har installert en-US som språk, og ikke bare norsk. Hvis ikke, vil Windows Store være så og si tom når du browser eller søker i den. For å finne oppsettet trykk Win, Win + F, søk etter “language” i “settings”.

Uten dette, er det fint lite å finne i Windows Store (per september 2012):

(Summary in English: if you are not native to the US, make sure you have en-US installed as a language in Windows 8. It does not have to be the preferred language. Otherwise, the Windows Store will probably have very little apps – only apps that explicitly supports your native language/culture)

Powershell gotchas: calling a function

Consider the following code:

function f($a, $b, $c) {
	"f: `$a=$a, `$a.GetType()=$($a.GetType())"
	"f: `$b=$b, `$b.GetType()=$($b.GetType())"
	"f: `$c=$c, `$c.GetType()=$($c.GetType())"
}
f 1 2 3   # call f with three integers as parameters
f 1,2,3   # call f with an array of three integers
f (1,2,3) # as above

The gotcha here is not to fall into the trap to use a C#-like or Java(Script)-like syntax where parameters are separated by commas. The comma in Powershell is always an array constructor operator, and takes precedence over function application. (Which also means that adding paranthesis will yield the same result). The code above will result in:

f: $a=1, $a.GetType()=int
f: $b=2, $b.GetType()=int
f: $c=3, $c.GetType()=int
f: $a=1 2 3, $a.GetType()=System.Object[]
You cannot call a method on a null-valued expression.
At ...function-application.ps1:4 char:11
+ $b.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $b=, $b.GetType()=
You cannot call a method on a null-valued expression.
At ...function-application.ps1:5 char:11
+ $c.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $c=, $c.GetType()=
f: $a=1 2 3, $a.GetType()=System.Object[]
You cannot call a method on a null-valued expression.
At ...function-application.ps1:4 char:11
+ $b.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $b=, $b.GetType()=
You cannot call a method on a null-valued expression.
At ...function-application.ps1:5 char:11
+ $c.GetType <<<< ()
    + CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
f: $c=, $c.GetType()=