All posts by Rikard Ottosson

About Rikard Ottosson

.NET developer. Father. Couch potato. Old, cynical, willing to learn, but quick to judge. Likes old hard rock. Hope to buy more guitars.

Windows Phone 6.1

I managed to lose my employer’s Nokia N82 and as punishment by my boss he stuck me with an HTC Touch Cruise Windows Phone Classic 6.1 phone that nobody had wanted to use since 2008. I have tweeted about my findings with the hashtag #punishmentphone.

In short, the experience has been mixed. Synchronization with Google Apps works like a charm with e-mail, contacts and calendar and the messaging function is quite OK in the way e-mail works and the SMS part has conversations just like the iPhone. Sadly, though, the Windows Mobile general feel remains with very bad tactile feedback from the touch interface and a borderline unusable virtual keyboard and having a Windows interace on a phone means that user stories like “Create new SMS” or “Make a phone call” be at least a few clicks too far away for comfort. Oh, and another pet peeve: When the phone boots, it throws the SIM-card PIN-code dialog at me first, but that gets hidden by the WinMo desktop and I have to go in to the comm manager and disable the phone and reenable it to get the PIN dialog to a place where I can actually punch the numbers in. WinMo has improved since before, though as the phone has only died on me once so far for no reason, which is vastly better than a QTek S100 I wrestled with years before.

NewID

Many of the companies in the former Way Group have now fusioned under the name Jayway, among them my beloved Dotway.

My dear employer has gone from being the key part in a cluster of separate expert companies (Dotway being the finest in .NET, Jayway ruling the world of Java, Testway laying down the law in the world of testing and Leadway striving forward in project management with Realway soldering on (sic) in the embedded systems field)  and fusioned ourselves into one formidable entity under the name Jayway. To this end we are all gathered under the jayway.com domain and all previous references to Dotway should now be pronounced Jayway.

Using the NHibernate OR-mapper

I have decided to go ahead and set up a class that covers the basics and a few more advanced features of NHibernate. In order to take part in the class, please contact Dotway Stockholm at stockholm@dotway.se

As Domain Driven Design has won followers over legacy Data Driven Design people are focusing on mapping a business case directly into a set of objects that describe the problen space and true workflow, solving the problems the customer wants to solve and thus focus more on stringent, understandable and maintainable systems rather than focusing on what data the system will contain and how to store it cleverly, systems for abstracting away object persistence .have emerged. In the Java community Hibernate has been the big name over the years and in .NET NHibernate is establishing itself as the major player being the foundation for several solutions for automated persistence such as Castle ActiveRecord with the ActiveWriter modelling toolset.
 
This class is directed towards experienced .NET developers looking to migrate to NHibernate in production, either wrapping legacy databases or going greenfield domain-first. It covers a variety of tasks from the basic “getting started” via configuration through XML as well as FluentNHibernate to complex persistence solutions with some comparison to other persistence solutions such as Linq2SQL.
Topics covered in this class:

  • OR-mapper. Why?
  • Getting started
  • NHibernate vs … part I
  • Implementing a Sample Case
  • Session model
  • Lazy Loading
  • HQL
  • Schema versioning and deployment
  • Best practices
  • Worst practices
  • NHibernate vs … part II
  • Troubleshooting
  • Performance tuning

Starting with a very basic example of an ASP.NET MVC website I will expand and elaborate on a number of features in NHibernate, such as configuration, transactions, session scope, various key types, numbering schemes and lazy loading to show how to solve problems with NHibernate and how to retrofit NHbernate on top of existing schemas as well as how to create and version greenfield schemas. I will use a demo version of nhprof to demonstrate how the features, settings and tweaks as well as the chosen platform affect the SQL generated

I hope the class will instill a greater understanding of and confidence in NHibernate for use in your current project. If you wish there will be a fistful of code you will be able to use as a starting pont for your own exploration of NHibernate and its features.

The Dark Side

Back in the nineties when I trained as an apprentice coder at the University of Umeå, I was first exposed to the Dark Side. It was very seductive with an intuitive TCP/IP stack, simple signal management conventions, concise UI:s, lean config files, powerful scripts, nifty daemons and of course the Bible: Advanced Programming in the UNIX Environment by W. Richard Stevens. I marveled at the distributed GUI, broken and deeply insecure though as it was, I admired that multi-user security concerns had been addressed back in the ‘70s already, not as an afterthought in 1989. Then I was brought out in the real world and began appreciating GUI conventions,  speed of implementation, solving customer problems and so on and came and joined the Just and Fair in the Microsoft camp and haven’t strayed since. Much.

But

But now and then the urge to complicate things gets stronger and stronger and with members of my immediate family having been lost to the Others for years now, the lure became overwhelming. After years of propaganda from my father I finally decided to install OpenSolaris on a virtual machine. Of course Solaris will not install on Windows Virtual PC Beta. It does not recognize any of the virtual SATA devices and thus cannot install. What to do? Well I gave up of course.

For a week or two until I thought I should make a serious attempt and actually dowloaded Sun’s VirtualBox.

VirtualBox vs Windows Virtual PC Beta

I really wanted to hate it, it not being made by the Just and Fair folks at Redmond. However, it is difficult to argue with 64 bit CPU high performance virtualization with USB, disk and network integration. It sucks the life out of the host machine, but in return both guest and host perform acceptably, lest you allocate too much memory to the guest “computer”, unlike with Windows Virtual PC where you get low performance (but better than Virtual PC 2007) on the handful of platforms it does handle.

Of course, I popped in the ISO in an empty Virtual machine (ironically using the same empty VHD Windows Virtual PC Beta created but couldn’t make available to Solaris) and of course the setup just chugged along event free. A vast improvement over previous UNIXes I installed back in the day. It refused to give me any options but to fill my VHD with the One Solaris partition to bind them all. None of that allocating partitions to /root, /home, /usr/local et c-business that used to be 90% of the fun of trying to set up a Unix style system.

Stereo? Not for me

Of course, once everything is set up you want to do stuff. Back in the day I would have set up FTP and the Apache httpd and created logins for friends and acquaintances and set up the firewall to allow for SSH:ing in to my computer. My computer in this case just being nothing but a figment of my laptop’s imagination, that would be even more pointless than it was back in the day. So: What to do? Weill, of course: Develop in .NET! After all, if I am to achieve global supremacy, I need to be able to code on Solaris as well, at some point.

This is where it all came back to me. Because it is a proper UNIX and not some humble Linux, allegedly, they haven’t gotten mono to run consistently on Solaris. The hours of gunzipping and ./configuring and make believing. compile errors upon compile errors. Downloaded various other package managers to appease the evildoers. Nothing I did could make mono build, despite gigabytes of source code. Ah well… Now I gave up properly.

OpenSUSE

Until I tried OpenSUSE, that is. Similar scenario, clean VM in VirtualBox, popped a physical DVD in my drive and shared it to VirtualBox, the empty VM booted and started the Open SUSE setup. I got to fiddle with my partitions (yay!) but I chose not to. Again, nothing fun happened during install, it just worked. A couple of reboots later I was able to login on my new machine, open the package installer, select everything mono-related and click install. After 20 minutes or se everything was downloaded and installed, and I just went to the Start menu(or what do you guys call it? The non-Start menu?) –> Applications-Development-Integrated Development Environment (monodevelop) and start to code. Very painless. Press play, off you go and you have ASP.NET being hosted on a Linux machine.

Then I noticed that my window was a bit on the smallish side, I would have preferred a higher resolution, like the one I had on the Solaris VM or so, so I go into the yast2 thingy and change display settings to something I consider appropriate and save the settings. I am instructed to restart the window manager, so I reboot the computer (yes I know. but it involved less interaction) and login again. Everything looks fine until after 5 seconds when the display gets garbled and I’m thrown out back to the login screen. I try all kinds of failsafe settings but to no avail. Of course I could manually edit a conf file somewhere to solve the issue, but Google has yet to reaffirm its friendship with me by coming up with a link to a Q&A forum where the question has been answered,

So?

Back to the good side it is, where stuff just works. Of course you can also end up in situations where stuff just doesn’t work as well (oi! CRM4! There’s this new thing, Windows Server 2008. It’s been out for a good two years now!), but resources are more plentiful and as an added bonus: you feel better cursing big successful company than makers of free software.

Windows Virtual PC Beta: -1

While test driving Windows 7 RC I suddenly needed to run a virtual machine to avoid dual booting to access a few key applications that could not survive the combination of an x64 platform and Windows 7. Either one on its own would have been fine but the combination was lethal. Killing two birds with one stone I felt the time was right to test drive the Windows Virtual PC beta and Virtual Windows XP. The first day I managed to completely ruin my XP virtual machine and had to start over. This was the start of a healthy dose of stupidity tax in combination with a rather opaque interface to the virtual machines which still only dented the superb first impression slightly.

The product

The user interface is a custom Explorer folder, supposedly containing actions for creating and managing virtual machines. Not so in my case, despite reinstalling twice, I only have a fancy icon in the toolbar and that’s it. No actions avaiable. This doesn’t hamper proceedings much, though as I can still double click a virtual machine file (*.vmcx) to start it. How do I create a virtual machine, though? Google tells me that to create a new virtual machine I type vmcwizard.exe in the start menu search field and press enter. Google is right. Once created, you configure the machine by right clicking the file in the explorer and clicking Settings. Here you get a properties box that has more in common with Windows Server 2008 and Hyper-V than with Virtual PC, which is of course great.

The integration features make the VM able to talk to USB devices on the physical computer aside for the usual disk, printer, clipboard and sound integration also available. In order to run old (or just badly made 32-bit only) applications virtually you look at the Auto-Publish tab and enable that feature. This means that application shortcuts under the All Users Start Menu end up published in the host-OS Start Menu under All Programs –> Windows Virtual PC –> [Virtual Machine Name]. Any notification icons displayed in the virtual machine while it is running in application mode will also be forwarded to the host OS notification area. To enable this, you may be wise to store credentials for a user account on the VM that has proper authorization to run the programs installed. This way the integration becomes seamless.

Virtual Windows XP is thus just a preconfigured Windows XP SP3 image with auto-publish checked. Nothing magical that you couldn’t make yourself provided you had a spare license for Windows XP, obviously.

The user experience while working with Windows Virtual PC is excellent compared to old Virtual PC 2007, because it feels just like Hyper-V for 2008 even though Hyper-V has superior performance to Windows Virtual PC, allegedly.

Problems? Oh yes. The virtual Windows XP wants to update itself through Windows Update. After it does, the virtual machine is Initializing, only showing a progressbar that suddenly starts over. After X number of iterations, I found, on non-Microsoft parts the Internet again, the shortcut Shift+Esc which shows the console instead of the progress bar. Lo and behold: Windows XP was BSOD:ing so the VM was rebooting continously! Not surprising since it’s XP, but it still is annoying since I’ll have to recreate my VM again which is boring. A utility which salvaged VM:s killed by Windows Update would be a nice-to-have trinket.

Also, integration just stops working in a few cases, and there is no way of forcing it on without tens of thousands of reboots which may or may not have the desired effect. No indication from either guest OS, host OS or VM player what the problem is. These things are extremely frustrating and could so easily be avoided.

An aside

I have a few design guidelines for Working Software, note that these are completely diametrically opposed to guidelines for security and stability, but this is for those of us who need to actually work for a living:

  • Never check for preconditions before you try something*
  • Never use locks. Don’t have shared write access to global resources, dummy.
  • Unless you risk actually destroying something valuable**, never mind errors, just continue.
  • Incorporate DDoS code to punish non-responsive servers. This is the only way.
  • Automatically kill processes locking the file you need. Those processes are never vital, statistics say***,

*90% of the case your check will be overly pessimistic, especially if you check version numbers. They are always a bad idea
** This is the case in less than 0,1% of production code. Mostly you get corrupt data which is, again, important in only a small percentage of the cases. Like I wrote initially, this is not for the people looking for correct or secure software, only software that delivers.
*** This claim is completely bogus. I mean the percentages above were complete fabrications as well, but this one tops them all.

Composite Application Guidance for WPF

Because my esteemed colleague Carl Kenne outed his excellent blog on TDD and WPF I felt I should probably put together a little something re: the CAG for WPF and Silverlight. The idea behind the Composite Application Guidance is to enable decoupled applications in WPF and Silverlight, utilizing a shell window, a dependency injection container, separate modules providing views that are displayed in regions either directly in the shell window or nested in regions provided inside the modules. For the conceptually isolated modules to communicate between each other a dedicated messaging system is created. Composite Events, to which separate modules subscribe to and others publish.

So what’s the point?

The point behind the guidance package is that it helps you structure your WPF application in such a way that you design a very loosely coupled system from the beginning. If you don’t have any use for module separation from the beginning, fine, make all your functionality reside in one module, that’s fine. You may want a few services, you may just want one, that’s fine too. The point is: Even with your one module consisting of a single Service managing one Model class and with your single Controller using one PresentationModel class to feed a single View xaml-file, you still have separated all your concerns, making testing a doddle with you being able to pass any mock object in just implementing the appropriate interfaces. You easily just make two different configurations for the DI-container of your choice for test and production environments.

So how do I get started?

Download the Composite Application Guidance package using the link above and pay attention to the requirements they specify right there on the download page. As you can see from the first page, one of the key new features introduced with this version of the CAG for WPF and Silverlight is that you can make Silverlight applications and WPF applications on a shared codebase using a nifty Project Linker. Less code is good. OK, so download the source code, open the shipped solutions and build them.

After that you are ready to create a solution and to get a feel for what this is and how it works.

Open up Visual Studio and get on with it

Create a WPF project called CompanyDashboard.Desktop (if you want to follow this story in detail, otherwise call it whatever you like). Use the Open in Windows Explorer menu option in Visual Studio and create a folder called Library.Desktop. In a new Windows Explorer window, open up your CAG source folder and browse down the Composite.UnityExtensions\Bin\Debug folder and copy everything pdbs, xmls and all into your new Library.Desktop folder. From Visual Studio, Add Reference and Browse to the folder and add everything. Rename (using the Refactor menu option, obviously) the Window1.xaml to Shell.xaml.

Add a class library project called CompanyDashboard.Common to your solution. Rename the Class1.cs to Constants.cs and add a public const string MainRegion containing the string value “MainRegion”.

Make it so that your shell.xaml looks like below:

<Window x:Class="CompanyDashboard.Desktop.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cal="http://www.codeplex.com/CompositeWPF"
    xmlns:common="clr-namespace:CompanyDashboard.Common;assembly=CompanyDashboard.Common"
    Title="Company Dashboard" Height="600" Width="800">
    <StackPanel>
        <ItemsControl Name="HeaderRegion"
                  cal:RegionManager.RegionName="{x:Static common:Constants.HeaderRegion}"
                  Height="200" Width="800" />
        <TabControl Name="MainRegion"
                  cal:RegionManager.RegionName="{x:Static common:Constants.MainRegion}"
                  HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        </TabControl>
    </StackPanel>
</Window>

The XAML above defines two regions, a header region that is an items control and a main region which is a tab control. Now the point of these regions will be explained further below, but for now just accept that this is what we are going to do.

Create your Unity bootstrapper

Add a class to your CompanyDashboard.Desktop solution. Call it CompanyDesktopBootstrapper and let it inherit UnityBootstrapper like so:

using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;
using System.Windows;
namespace CompanyDashboard.Desktop
{
    class CompanyDashboardBootstrapper :
         UnityBootstrapper
    {
        protected override DependencyObject
              CreateShell()
        {
            Shell shell = new Shell();
            shell.Show();
            return shell;
        }
        protected override IModuleCatalog
              GetModuleCatalog()
        {
            ModuleCatalog catalog =
                 new ModuleCatalog();
            return catalog;
        }
    }
}

The UnityBootstrapper class is abstract and needs help creating a Module Catalog and creating the Shell window, this is what we do above. Since the bootstrapper wants to set up all the instances we need to rock’n’roll we shall disable the built-in WPF startup-object management and start the UnityBootstrapper instead. To accomplish this we shall attack the App.xaml and App.xaml.cs files. In the app.xaml-file, remove the StartupUri attribute from the Application element. In the app.xaml.cs, add the following function:

        protected override
            void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            CompanyDashboardBootstrapper bootstrapper
              = new CompanyDashboardBootstrapper();
            bootstrapper.Run();
        }

This way, the bootstrapper is called and on its own creates the Shell window and any dependencies that are necessary or that become necessary with future versions of the software.

At this point you can press play on tape and view your empty CAG application.

Wait a minute… What are we doing here?

The sample will create a composite application bringing together information from a two sources, a “CRM system”, which will be the main source of customer information, and an “Order system” plus an extra module looking up address info on google maps and stuff like that. Whenever a customer is selected, the word gets out (Composite Events) and the other modules scramble to present their own information in context.

Adding some modules

Add a Class Library project to the solution and call it CompanyDashboard.CRMModule. Feel free to use Solution Folders to create some order in your solution explorer. Add another module called CompanyDashboard.SalesModule. What’s going to happen is that the bootstrapper will load the modules from a folder located under the application base folder. To enable this, a few things need to happen, such as post-build events that copy the DLL:s from the module output folders into the Modules folder under CompanyDashboard.Desktop/bin/Debug. Before we get to that though, we need to set up some references.

You will need the following references in a typical Module:

  • PresentationCode.dll
  • PresentationFramework.dll
  • WindowsBase.dll
  • Microsoft.Practices.Composite.dll
  • Microsoft.Practices.Composite.Presentation.dll

In CompanyDashboard.CRMModule, rename Class1.cs to CRMModule.cs and add a using statement for Microsoft.Practices.Composite.Modularity and let your CRMModule class implement the IModule interface. In order for your module to be dynamically loaded, you need to also add the attribute [Module(ModuleName=”CRMModule”)]. For the Sales Module, which will depend on the CRMModule, an additional attribute will need to be specified. The SalesModule.cs will look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Composite.Modularity;
namespace CompanyDashboard.SalesModule
{
    [Module(ModuleName = "SalesModule")]
    [ModuleDependency("CRMModule")]
    public class SalesModule : IModule
    {
        public void Initialize()
        {
        }
    }
}

This will now mean that the CRMModule will be initialized first, and then the SalesModule. In order to add a module to this application, all you need to do is to create a DLL, give it the right attributes and deploy it in the Modules folder and you have your new features accessible. We will demonstrate this with Module no. 3 eventually.

Come back in the next post to see how views are created and filled with data from separate data stores.