Wednesday, July 14, 2010

Pivot and Panorama support in Windows phone 7 beta






The title of this blog post is a little confusing (it was meant to be!) in that there is no support for the Pivot and Panorama controls in the latest bits of Windows phone dev tools. The controls pictured above are courtesy of Stephane Crozatier.

Those controls are freely available on codeplex to download but were designed for the CTP bits of Windows phone. So as there were some breaking changes between the CTP and the recently released beta they won't work out of the box. But it very easy to fix.

Firstly you need to do delete the Microsoft.Phone.* references and add the Microsoft.Phone.dll to the project. All those additional dlls have been merged into Windows.Phone.dll.


Then you'll need to clean up the XAML namespaces. Luckily for me I have ReSharper 5.0 installed and all I have to do is press Alt+Enter and it fixes all my problems! nice



Now if you want the sample WeatherForecast app to run you need to do 1 last thing. That is the ApplicationBarIconButton class now has a mandatory Text property so you need to set this property for each of the buttons in the MainPage.xaml file.

Now once I clean up all that XAML, I rebuild and run and I get...



Sweeet....

Another nice cool thing with this emulator over the older Windows Mobile emulators is that you can do a ALT+Prnt Scrn to get a copy of the current focused window. You can't do this on Windows Mobile emulators.


Windows phone UK User group






I just learn't there has recently been a Windows phone 7 UK user group setup. The first meeting is 28th July at Conchangos offices in London. http://wpug.net/.

Microsofts Paul Foster and Rob Fonseca-Ensor will be speaking. There is now a wait list on the event but worth a try right!

Monday, July 12, 2010

First impressions Windows Phone Developer Tools beta

I just installed the beta bits released this evening and as per the CTP the install experience is brilliant. Except with the beta the greatest thing is support for Visual Studio RTM. So unlike the CTP, even if you had VS RTM installed, then you installed the WP7 dev tools, the installer would install the CTP of VS express and not integrate with VS RTM. Actually I found a whole bunch of errors when attempting this with the CTP.
New project in VS 2010 RTM (no support for VB.NET though):


However this build is good. I'm running VS 2010 Ultimate and VS 2008 Team Suite and this build integrated with VS 2010 RTM nicely.

It is also worth noting in this release of WP7 dev tools, you get Expression Blend 4 for Windows Phone beta. In the CTP you had to download this separately.
So experience so far is great, well done Windows Phone 7 team.

Emulator running bing:



I'll post my experiences of actually writing WP7 code using these bits in later posts. In the mean time you can download and try for yourself.

Windows Phone Developer Tools Beta is here

Announced today at WPC. Get it from: http://www.microsoft.com/downloads/details.aspx?FamilyID=c8496c2a-54d9-4b11-9491-a1bfaf32f2e3&displaylang=en

Check out this post on breaking changes from CTP to Beta: http://blogs.msdn.com/b/jaimer/archive/2010/06/28/migrating-apps-from-windows-phone-ctps-to-the-beta-build.aspx?wa=wsignin1.0

I'll post my feedback once I've installed it and tried it out.

Notice this under "System Requirements:"

This Beta of the Windows Phone Developer Tools is compatible with the final version of Visual Studio 2010


This has made my day :)

Friday, July 02, 2010

Testing Motorola EMDK WLAN implementation on the desktop

I've been writing about testing recently and whether or not to use device test projects or desktop test projects. You can read my view on this in a previous blog post.

No doubt if you have written code for any of the Motorola rugged devices (or other rugged OEM devices) you might have encountered the EMDK WLAN class (or similar if not coding against the EMDK) - which wraps the low-level mobile specific Motorola Fusion API. This is a prime example of why you should use a desktop test project rather than device project. Hang on, you just said the Fusion API can only execute on the device, so don't we need a device test project? No. The reason is simple, again if you have a continuous integration, automated build process setup, your tests will be executing on the build server so you won't be able to execute those tests against a real Motorola device. If you have a device test project, the best you can do is execute those tests on the Windows Mobile emulator - but what will this prove? In this case this is really no different in terms of a test problem than executing them on the desktop.

So this is a reason to write your WLAN tests within a desktop test project. Let me demonstrate...

The WLAN class that comes with the EMDK (Symbol.Fusion.WLAN.WLAN) is a prime example, to make things worst, it doesn't implement an interface, take a look:



So this makes it almost impossible to test. Instead how I have overcome this problem is to write an adapter that wraps the WLAN class, then mock out the adapter using Rhino Mocks. Observe the following WLAN implementation, the interface isn't important:
public class MotorolaMC75WLAN : IWLANService
{
private readonly IMotorolaWLANAdapter _adapter;
private bool _disposed;

public MotorolaMC75WLAN(IMotorolaWLANAdapter adapter)
{
_adapter = adapter;
}


public void Enable()
{
if (!_adapter.IsEnabled)
{
_adapter.Enable();
_adapter.PowerStatusChanged += OnPowerStatusChanged;
}
}

private void OnPowerStatusChanged(object sender, PowerStatusChangedEventArgs e)
{
//raise events to interested parties....perhaps using some sort of event aggregator
}

public void Disable()
{
if (_adapter.IsEnabled)
{
_adapter.Disable();
_adapter.PowerStatusChanged -= OnPowerStatusChanged;
}
}

public bool IsEnabled
{
get { return _adapter.IsEnabled; }
}

public void RenewDHCP()
{
_adapter.RenewDHCP();
}

public void Connect()
{
_adapter.Connect();
}


#region IDisposable Members

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

#endregion

private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
Disable();
_adapter.Dispose();
}
_disposed = true;
}
}
}
So that is our high level implementation that can be easily extended and contains no low-level mobile code. The adapter in this case is injected and can be anything we want it to be which allows us to test this class easily on the desktop.

The next thing is our actual adapter. The interface for the adapter looks like this
public interface IMotorolaWLANAdapter : IDisposable
{
void Enable();

void Disable();

bool IsEnabled { get; }

void RenewDHCP();

event EventHandler PowerStatusChanged;

void Connect();
}
The implementation is low-level that talks directly to the WLAN class (Fusion API). I'm not going to include a typical implementation for this but an example Enable() method might look like the following:
public void Enable()
{
if (IsEnabled)
return;

Symbol.Fusion.WLAN.WLAN command = null;
try
{
command = new Symbol.Fusion.WLAN.WLAN(FusionAccessType.COMMAND_MODE);
command.Adapters[0].PowerState = Adapter.PowerStates.ON;
}
catch (OperationFailureException ex)
{
//do something...
}
finally
{
if (command != null)
command.Dispose();
}
}
It simply enables the first adapter it can find. Non-of the real adapter is testable.

So if this were a device test project, we'd have to mock out the adapter by hand, then pass it in to the constructor to the MotorolaMC75WLAN class. But as we have decided to use a desktop test project we can use any mocking framework that we choose which enables us free of having to do the laborious hand mocking work.

You can download Rhino Mocks from here if you don't already have it: http://www.ayende.com/projects/rhino-mocks/downloads.aspx. Download the zip and extract it somewhere on your hard disk, then add a reference the Rhino Mocks assembly in your test project - there is only one dll you need to reference.



Add a
using Rhino.Mocks;
to your test class. Now if you wanted to mock out the adapter Enable method, in Rhino Mocks world it could look like the following using the newer triple A syntax:
[TestMethod]
public void ShouldEnableWLAN()
{
IMotorolaWLANAdapter _mockWLANAdapter = MockRepository.GenerateMock<IMotorolaWLANAdapter>();
IWLANService _wlan = new MotorolaMC75WLAN(_mockWLANAdapter);

_mockWLANAdapter
.Expect(x => x.Enable())
.Repeat.Once();

_wlan.Enable();

_mockWLANAdapter.VerifyAllExpectations();
}
So the only actual thing we are testing here is the real MC75 WLAN class and not the adapter. The code is fairly easy to read. We are simply telling Rhino Mocks to expect exactly 1 call to Enable() when _wlan.Enable() is called. The thing to bear in mind here is to ensure your actual adapter doesn't contain bugs as we can't automate those tests on the build server.

There you have it, a true mocking framework put at use in the mobile space.

If you want to learn more about mocking frameworks, use Google, there are millions of articles out there on the subject.

Thursday, July 01, 2010

Automated testing considerations for enterprise Windows Mobile projects - avoid a world of pain

I know in the past I have written blog posts on how to create unit tests that are actually executed on the Windows Mobile emulator which is great if you have mobile specific tests. But to be honest, when you are building large scale enterprise mobile solutions targeting a range of different devices i.e. Motorola, Casio, Intermec etc. Writing device specific platform tests for all these devices becomes quite hard to automate when using an application lifecyle management solution such as Visual Studio and TFS with its continuous integration and automated test execution support.

Even if you only support one type of device, when you do enterprise mobile development, using the tools mentioned above, you're not going to be able to automate those tests as part of a nightly build or even a CI build. As you will no doubt be using the vanilla Windows Mobile Emulators that know nothing about such specifics that you might be testing such as barcode reader, credit card reader, bluetooth stack etc. Instead you would normally write adapters or mock out implementation code when testing your barcode implementation. You'll generally never write an actual test that calls the true native code on that platform, why would you anyway unless it's part of an integration test. Ensuring you do this allows you to write unit tests, integration tests that do run as part of your nightly and CI builds that do improve code quality.

So what type of tests should you write for most of your code base, device or desktop? My advice is desktop even if you think your device project is small, there will come a time when your project becomes large and more complex. The benefit to targeting the desktop is the ability to use mocking frameworks. We tend to use Rhino Mocks and today there are 0 mocking frameworks available on the CF. If you start to go down to road of writing your own mocks, then you're entering a world of pain. When you think of it, most code can be tested on the desktop anyway. For things like data access, if you use SQL CE 3.5, then this can run on the desktop. For the features that require explicit device testing, then create a single device test project for this purpose and exclude it from the build definition.

Wednesday, June 30, 2010

Versioning team builds to match assembly version numbers

Have you ever wanted to version your team builds to match your assembly versions. Stuart Preston shows how to easily achieve this in Team Build 2010 over at: http://stuartpreston.net/blog/2010/05/02/simple-assembly-versioning-with-team-build-2010/

I've just tried this and it works nicely, great stuff!

Monday, June 28, 2010

Automating your Windows Mobile 6.x builds on TFS 2010

If you have recently attempted to build your Windows Mobile 6.x code using the new TFS 2010 recently you might have received this error:

(81): The imported project "C:\Windows\Microsoft.NET\Framework64\v3.5\Microsoft.CompactFramework.CSharp.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

It is pretty clear as to what the issue is, so how do you fix this? Well you can install Visual Studio 2008 (Device development is not supported on VS 2010) on your build server - not nice, but then this won't fix my issue here. Notice the path above. The smart device project is looking in the 64-bit location for the Compact Framework build targets files: C:\Windows\Microsoft.NET\Framework64. As my build server is running on Windows Server 2008 R2 - which only comes in 64-bit edition, it makes sense to use 64-bit tools.

The easy fix for this type of configuration is to install the .NET Compact Framework 3.5 Redistributable which can be found here: http://www.microsoft.com/downloads/details.aspx?FamilyID=e3821449-3c6b-42f1-9fd9-0041345b3385&displaylang=en. Install that package on the build server which will allow your code to compile.

Then download the .NET CF 3.5 Power Toys - this will give your the Compact Framework build targets that MSBuild needs. This can be downloaded from here: http://www.microsoft.com/downloads/details.aspx?FamilyID=c8174c14-a27d-4148-bf01-86c2e0953eab&displaylang=en. Again that package needs to be installed on the build server. You may think it is odd that the build targets are included in this package, then so did I. They are also included with VS2008 but installing the Power Toys is a much better solution as it's a lot smaller install.

Now remember with my configuration I mentioned earlier, I am running 64-bit server, as there is no 64-bit edition of .NET CF Power Toys, the build targets get installed to the 32-bit location on the file system: C:\Windows\Microsoft.NET\Framework\v3.5 but by default my build definition is set to "Auto" which will choose the 64-bit edition first, then use the MSBuild path to find the build targets. This will still result in a failed build because the 64-bit edition will be running from: C:\Windows\Microsoft.NET\Framework64\v3.5 and that path doesn't contain the files we need. So a simple change to the build definition to use x86 is needed:

Once you make that change, queue a new build and your build should succeed.
As for getting VS 2008 talking to TFS2010, I'll write a post on getting that to work. There is a lot of content on this in the community but a lot of it didn't work for me.

Thursday, May 27, 2010

Windows Phone 7 Series running on a modified Samsung Omnia



Looks very slick...voice in French.

Installing Windows 7 on a netbook


I recently bought an Asus Eee PC 1001 HA netbook for my wife to use for a really good price as it was an ex demo (end of line). This model has been superseded by a better model that includes a slightly faster CPU Intel Atom 1.66Ghz as the 1001 has a Intel Atom 1.6Ghz N270 processor. The newer model also comes with Windows 7 as oppossed to Windows XP which is what the 1001 model comes with. I have to say, I think it is brilliant.

As mentioned it came with Windows XP Home Premium edition but as this was for my wife she didn't care. But after getting home I relised I couldn't join it to the Windows Server 2008 domain controller because Home Premium doesn't support Windows Domains. So she couldn't print, fax, access family pictures, get an IP address from the DHCP, access TFS..(not really, shes not a coder!) etc etc You can't even access a network UNC path from Home Edition.

So XP clearly had to come off. So we installed Windows 7 Ultimate x86, bearing in mind this little machine only has 1gb of DDR2 RAM and it runs very well indeed.

But the problem I found was installing the Windows 7 OS without a CD drive and no access to a network share? All I have are USB ports. So as I don't have a optical USB CD drive, I simply downloaded Windows 7 USB/DVD Download Tool from codeplex, found here: http://wudt.codeplex.com/ It is actually written in C# under Visual Studio 2008, with full source code available to download.

This tool allows you to create a bootable USB flash card. So all I had to do was create a bootable USB flash card using the Windows 7 ISO, configure the BIOS on the Asus to boot from USB, install Windows 7, then job done.

Windows 7 USB/DVD Download Tool

In fact this tool works with DVD's as well, so it will be useful for future DVD burning.
This blog talks about disabling various Windows 7 services for optimization on a netbook pc, but to be honest I didn't need to disable anything, it just works really nicely.

I did forget to mention that I download Asus's drivers for optimal WLAN, display adapter etc to better performance and to get the machine to behave correctly.

Good job Asus...

Saturday, May 22, 2010

Moving Windows Azure CTP account over to RTM - don't forget to remove any unwanted services!

If like me you recently moved your Windows Azure CTP account over to an RTM account, ensure you delete any services that you don't want as you might be charged. I completely forgot I had 2 services deployed in Staging and 2 services deployed in production when I moved my account over. So a few weeks ago I had a bill for £187.10! I had been viewing my bills regularly and didn't see any charges until 24/04/10. So the charges were from 25/03/10 - 24/04/10.

The important thing to note here is the pricing model in Windows Azure - I'm talking about hosting services which is the deploying of services and running services in the cloud bit of Windows Azure - not the Service Bus or SQL Azure - they have different pricing models.

The charges are based on "compute hours". Although do note there are two types of pricing models within Azure. The first is a pay as you go type model so you only pay for what you use. The other model is a fixed contract where you agree to a fixed discounted monthly fee for a given time frame and any excess usage is charged at the standard rate.

Do be aware, no matter whether your services are being used or not even if your services are not running this still eats into your "compute hours". It sounds unfair from the outset, but I don't think it is unfair as for those charges you get a dedicated VM, CPU, memory etc to your services. So you can be sure you'll have the resources available to serve up requests when needed.

So as I am an MSDN Premium subscriber, I opted for the promotional offer of "free" services. So under this offer you get 750 "compute hours" under Windows Azure, 1,000,000 ACS transaction requests on AppFabric, 3 web edition databases etc. See here for more info on this promotional offer: http://www.microsoft.com/windowsazure/offers/popup.aspx?lang=en&locale=en-US&offer=MS-AZR-0005P

Utilization over the "free" 750 hours will be charged at the standard rate.

Of course that works out to be one service constantly deployed in the cloud for 24 hrs a day for 31 days. So essentially free.

Now regarding my bill I received, the good news is Microsoft refunded me the £187.10 due to the fact I forgot to remove the services and the fact that I didn't realize they were still deployed as I have only been using the Service Bus within Windows Azure lately (now known as the AppFabric). So I am grateful to Microsoft for doing this as they legally didn't have to.

So when I noticed the bill, the first thing I wanted to do was delete the services to prevent further costs mounting up.

So I went to the Windows Azure maintenance portal over at http://windows.azure.com/ clicked on Windows Azure and noticed the services. But the Delete button was disabled:



This is not particularly intuitive, but you have to click "Suspend" which is the same as stop. Then the Delete button becomes enabled that allows you to delete the services!



Wednesday, May 12, 2010

MSTest: Not Executed after aborting a debugged MSTest

If you try to debug a MS Test unit test in VS 2008 but stop the debugger before the test is completed (abort the test) the test status will be marked with "Aborted". Which is fine and expected. But if you then try to execute any other test, whether this is debugging a test or just executing a test, it will fail and the status of all attempted tests will be "Not Executed". And from here in no tests will ever execute again..until you kill process "vsperfmon.exe". If you kill that process, then unit tests will then continue to execute.

This defect seems to be fixed in VS 2010 which is great but it still exists in VS 2008 which is a pain as Windows Mobile developers still require VS 2008 to develop WM apps (this defect applies to both desktop and device tests).

There is a bug report on Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/299925/after-debugging-a-unit-test-vsperfmon-exe-must-be-killed-to-be-able-run-further-tests

As always, if you find this defect annoying, then use the site above to vote for a fix.

This bug has been around for sometime and it's only today I learned the workaround!

To inject IServiceLocator or not to inject

I had a discussion the other day about it being a bad idea to inject the IServiceLocator as a dependency into the constructor of consuming types. Now I'm talking about the Common Service Locator by the p&p team at Microsoft (http://commonservicelocator.codeplex.com/) but to be honest this applies to the Service Locator pattern in general.

The argument was based on the fact that it makes testing more difficult as you not only have to mock or provide types to the constructor but you have to add them to a service locator if injecting the service locator interface.

There are valid reasons for not doing this but we don't live in an ivory tower and sometimes we need to pull types from the container at runtime that we simply do not know at design time. In this case it makes perfect sense for using a service locator, right? as the whole point of the pattern is to abstract container from implementation code.

I'm curious of other developers feel for this and their approach as to whether they do this or not, and if so why.

Friday, April 23, 2010

Turning off the context menu scrolling in VS2010

UPDATE (28/03/2011): This has been fixed in VS2010 SP1: http://www.simonrhart.com/2011/03/unnecessary-context-scrolling-in-vs.html

If you have noticed in VS2010 when right clicking something and displaying the context popup menu. You sometimes get a scrollable menu appear in which you have to use the mouse wheel, or press the up or down arrows that are displayed for this type of menu to see all items in the popup menu.

Sadly turning off this "feature" is not possible as it seems to be a bug: https://connect.microsoft.com/VisualStudio/feedback/details/532806/context-menus-open-in-scrolling-mode-while-there-is-place-to-show-the-whole-menu/?wa=wsignin1.0

If you find this bug annoying enough, please vote on the connect site so hopefully we will get a hot fix rather than having to wait for SP1.

[TFS 2010] (1835): Task failed because "resgen.exe" was not found

I recently upgraded my build server from TFS 2010 RC (which worked fairly well I have to say) - although its worth pointing out here that VS 2010 RTM doesn't work with TFS 2010 RC. You get all kinds of build errors.

I recently checked some code in and the build server gives me the following error:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (1835): Task failed because "resgen.exe" was not found, or the correct Microsoft Windows SDK is not installed. The task is looking for "resgen.exe" in the "bin" subdirectory beneath the location specified in the InstallationFolder value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A. You may be able to solve the problem by doing one of the following: 1) Install the Microsoft Windows SDK. 2) Install Visual Studio 2010. 3) Manually set the above registry key to the correct location. 4) Pass the correct location into the "ToolPath" parameter of the task.

So I have given in and installed Visual Studio on the build server and this seems to fix the problem! - I know this just doesn't sound right.... I could of tried and installed the Windows SDK on the build server but I do want to build Windows phone 7 Series apps on my build server and I know that bits in WP7 are not in the Windows SDK.

Wednesday, April 21, 2010

ServiceLocator.Current - calls the SetServiceLocator delegate everytime!

If like me you were under the impression that calling ServiceLocator.SetLocalProvider result would be cached when using static member ServiceLocator.Current then you'll be wrong.

I was surprised to find out that the ServiceLocator implementation passed to ServiceLocator.SetLocalProvider was created everytime I called ServiceLocator.Current.

I know I should always inject IServiceLocator into the ctor of the consumer types, but there are rare occasions that I need to use ServiceLocator.Current in static classes.

The implementation of ServiceLocator.Current looks like so:
public static IServiceLocator Current
{
get { return currentProvider(); }
}
currentProvider() is a good old fashioned delegate and looks like so:
public delegate IServiceLocator ServiceLocatorProvider();


So instead of doing this:
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(_container));
Do this:
IServiceLocator castle = new WindsorServiceLocator(_container);
ServiceLocator.SetLocatorProvider(() => castle);
You will get a load less garbage collections as a result.

If you have no idea what I am talking about in this post, please see the Common Service Locator by the p&p team at Microsoft here: http://commonservicelocator.codeplex.com/

Monday, March 29, 2010

Making use of the Command Pattern on Windows Mobile/phone

The Command pattern is a great pattern for abstracting business processes from your implementation code. This pattern is becoming very popular throughout different types of systems. Whether this is MVC thin client, fat clients such as MVP, MVVM.

The Command pattern works really nicely in combination with a IoC container and DI framework that I have talked about before on this blog.

Often it is desirable for a command to take a context or state. A command should only have one method and should only have one role (single responsibility). The interface for a command could look like so:
public interface ICommand<T>
{
void Execute(T context);
}
So our context here is a generic and is defined when the command is registered with the container.

So imagine we have a CRM system that when a customer is registered, we want to send that customer an email to confirm he/she has been setup correctly. You might have a domain model in this case that raises an event that is caught on the middle tier. When this occurs, instead of baking that code into the presenter/controller/business class, you abstract it out into a command. This not only makes your system more readable/maintainable but makes it easier to test too.

So in this case you could have a context class that contains the state such as the Customer domain object like so:
public class EmailCustomerConfirmationContext
{

public EmailCustomerConfirmationContext(Customer customer)
{
Customer = customer;
}

public Customer Customer{get; private set;}
}
Our command might look something like the following:
public class EmailCustomerConfirmationCommand : ICommand<EmailCustomerConfirmationContext>
{
private IEmailAdapter _emailAdapter;

public EmailCustomerConfirmationCommand(IEmailAdapter emailAdapter)
{
//inject dependencies here.
_emailAdapter = emailAdapter;
}

public void Execute(EmailCustomerConfirmationContext context)
{
_emailAdapter.Send(context.Customer);
}
}
Registering the command with the container (Compact Container - see previous posts on using this container) would look something like the following:
container.AddComponent<ICommand<EmailCustomerConfirmationContext>, EmailCustomerConfirmationCommand>();


Very clean approach. Of course the more dependencies you add to the command, the more complex it will become which means harder to test. So sometimes commands can become over complex. Bear this in mind when adopting this pattern.

Executing the command could look something like the following(assuming you are using the service locator):
var command = ServiceLocator.Current.GetInstance<ICommand<TContext>>();
if (!command.IsNull())
{
command.Execute(context);
}
In terms of handling errors etc, this could be handled via events using some sort of event aggregator pattern or the context itself to pass back data so the middle tier can act accordingly.

Sunday, March 28, 2010

TFS 2010 - the new build definition window

Jason Prickett has recently written a good article on the new Build definition window in VS 2010 - it's now dockable! It also has a new CI type named Gated-checkin. So developers need to have a green CI before they can checkin. Cool. I have been checking this new Gated-checkin feature out in the RC version recently, and I'm not sure it is working correctly. But will write back soon on my findings.

See here:
http://blogs.msdn.com/jpricket/archive/2010/01/19/tfs-2010-the-new-build-definition-window.aspx

Cool new feature with VS2010 and TFS 2010

I recently installed TFS 2010 RC x64 and only now got round to playing with it. I have to say once I got over the 'gremlins' during the installation everything else is pretty slick. There are many features I like and many that are going to make our lifes better.

One of the really horible things I hated about VS 2008 and TFS 2008 was after a partially succeeded build, opening up the build output in Build Explorer would only tell you something went wrong. In other words, the build partially suceeded. What? what does this mean? we know from experience this generally means a unit test had failed, but which one, and how do I fix it?



The only way to know which unit test had failed would be to troll through the build log - very painful when you have a large build script spanning multiple projects and 1000's of unit tests. I used to search for "FAIL". But some developers name their unit tests with the word "FAIL" in it so this doesn't help matters as it takes forever to find the real error.


So I created a really simple test project and added a test method that throw an exception, after I checked in under a CI build definition, I got the following:






Now, how cool is that! Weldone Microsoft. I think this will make many developers very happy. Look at the options we get at the top, [Open Drop Folder], [Retain Indefinately] etc it just makes our lifes easier. But the best bit, the reason for posting this blog entry, If I click "View Test Results" I get the following:







I'm impressed, this will make us so much more productive, a reason alone to upgrade. Excellent stuff!

Wednesday, March 24, 2010

MVVM - Windows phone 7 series pattern of choice

This post is really for my benefit (although it might help others). Here is a good article on the MVVM (Model-View-ViewModel) pattern that is showing a lot of interest in the WPF communities.

It is very much a different way of thinking when designing UI architecture although very similar to Fowlers relatively new Presentation Model pattern.

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Implementing an IoC container in Silverlight on Windows phone 7 series

I wrote a while ago about implementing a Service Locator for the CompactContainer on the Compact Framework here: http://www.simonrhart.com/2010/02/implementing-commonservicelocator-on.html

I mentioned in that post that I was using the CompactContainer for the CF freely available here: http://code.google.com/p/compactcontainer/ But now as I'm getting into Silverlight as it's the technology of choice when building applications for the Windows phone 7 series platform (as well as XNA), I needed an IoC container to solve the same problems on Silverlight as they do on the Compact Framework.

So I tried to port the container along with the ServiceLocator as blogged about before. I recieved errors in the ComponentCollection class after I tried to compile under Silverlight. Mainly because the following predicate methods such as:
  1. List.FindAll
  2. List.Find

Are not supported in Silverlight 3 as the documentation suggests. However, they are in XNA. As the generic List class belongs to mscorlib.dll (System.Collections.Generic) I noticed that mscorlib is shared for both XNA and Silverlight applications on WP7. I'm trying to find out why this is, or if there is a way of making those methods work in Silverlight.

Anyway it's not the end of the world that those methods are not in Silverlight, all I had to do was replace the following methods in the ComponentCollection class:


public List<ComponentInfo> GetComponentInfoListFor(Type serviceType)
{
return _list.FindAll(ci => ci.ServiceType == serviceType);
}

public ComponentInfo FindForService(Type serviceType)
{
return _list.Find(ci => ci.ServiceType.Equals(serviceType));
}

public ComponentInfo FindForClass(Type classType)
{
return _list.Find(ci => ci.ClassType.Equals(classType));
}

public ComponentInfo FindKey(string key)
{
return _list.Find(ci => ci.Key.Equals(key));
}
With the following code:
public List GetComponentInfoListFor(Type serviceType)
{
List<ComponentInfo> results = new List<ComponentInfo>();

foreach(ComponentInfo component in _list)
{
if (component.ServiceType == serviceType)
results.Add(component);
}
return results;
}

public ComponentInfo FindForService(Type serviceType)
{
ComponentInfo result = null;
foreach(ComponentInfo component in _list)
{
if (component.ServiceType == serviceType)
{
result = component;
break;
}
}
return result;
}

public ComponentInfo FindForClass(Type classType)
{
ComponentInfo result = null;
foreach (ComponentInfo component in _list)
{
if (component.ClassType.Equals(classType))
{
result = component;
break;
}
}
return result;
}

public ComponentInfo FindKey(string key)
{
ComponentInfo result = null;
foreach (ComponentInfo component in _list)
{
if (component.Key.Equals(key))
{
result = component;
break;
}
}
return result;
}
That was all I had to change everything else just compiled and worked. Full dependency injection worked as per on the Compact Framework. It seems moving to Silverlight is going to be less painful than I originally thought!

Tuesday, March 16, 2010

Windows Phone 7 Series emulator is running slow

When I first downloaded the new Windows Phone 7 Series developer tools CTP package, I found the new emulator to be very slow. This is the opposite of what I was expecting as the new emulator is built for x86, runs within a VM and supports hardware GPU host acceleration (so long as you have a gx capable of DirectX10 and at least support for DDI10) - which my laptop does.

To determin whether you have DirectX10 support and at least DDI10, run DxDiag.exe from the command-prompt and inspect the Display tab.

So what next, ok so I learned that in order for the emulator to make use of the GPU host from the VM I needed to enable HW virtualization. So how do I know if I have this enabled? this is enabled at BIOS level and normally disabled by OEMs by default. You can run the Microsoft Hardware-Assisted Virtualization Tool here: http://go.microsoft.com/fwlink/?LinkId=163321



So after running this tool I got the above. So this confirms that I didn't have hw virtualization enabled. After enabling it in the BIOS my Windows Phone 7 Series emulator is now running much faster!

More details about this process here (not WP7 specific): http://www.microsoft.com/windows/virtual-pc/support/configure-bios.aspx



New Windows phone series 7 forum

Ask your new Windows phone 7 series questions here:
http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/

Monday, March 15, 2010

Friday, March 12, 2010

Pre-order VS 2010 discount

Microsoft Visual Studio 2010 Professional will launch on April 12 but you can beat the rush and secure your copy today by pre-ordering at the affordable estimated retail price of £484.99.

If you use a previous version of Visual Studio or any other development tool then you are eligible for this upgrade. Along with all the great new features in Visual Studio 2010 (see www.microsoft.com/visualstudio) Visual Studio 2010 Professional includes a 12-month MSDN Essentials subscription which gives you access to core Microsoft platforms: Windows 7 Ultimate, Windows Server 2008 R2 Enterprise, and Microsoft SQL Server 2008 R2 Datacenter.

So visit http://www.microsoft.com/visualstudio/en-gb/pre-order-visual-studio-2010 to check out all the new features and sign up for this great offer.

Sunday, February 28, 2010

[ Application Tier ] TF255437: An error occured while querying the Windows Management Instrumentation (WMI) interface on the following computer:

You may have received the following error messsage while processing the Readiness checks during the installation of TFS 2010 CTP recently: [Application Tier] TF255437: An error occured while querying the Windows Management Instrumentation (WMI) interface on the following computer:. The following error message was received: Invalid Namespace.

So I though I'd check that WMI Service is running, and it was. After searching around it turns out I needed to enable WMI Compatibility for IIS 6 under IIS. You can enable this under Server Manager in Server 2008 and change the IIS role.

I think this 'feature' has been fixed for RTM of TFS 2010.

Friday, February 19, 2010

How to find out when your pre-release version of Windows 7 will expire

If you are still running pre-release Windows 7 OS like I am, it will expire soon. So how do you find out when it expires? Simple run winver.exe on the run menu and you'll get this. My copy expires on 1st March 2010.



Zune HD software for x64 platforms

Don't make the same mistake as I did in downloading the x86 version of Zune if you run x64 version of Windows.

Get the x64 version here: http://www.microsoft.com/downloads/details.aspx?FamilyID=9d25c2a6-cae3-49b0-a474-124fe79628a8&displaylang=en

Note: The x64 version is ~400mb where as the x86 is ~50mb !

Preview of Windows phone 7 Series

Thursday, February 18, 2010

It's Windows phone 7 Series time at MIX this year

It's no secret that MIX will be covering a lot of the Windows phone 7 Series content this year in Las Vegas (March 15th - 17th).

I just wish I was going, perhaps if I can find a cheap flight.....

Note: Windows phone sessions to be confirmed...

http://live.visitmix.com/

Wednesday, February 17, 2010

Implementing the CommonServiceLocator on the Compact Framework

You may have come across or used the CommonServiceLocator API as developed by the p&p team at Microsoft for your desktop applications in the past.

Before we go any further, it is worth explaining what a Service Locator is. The Service Locator is a pattern that abstracts your retriveal of components or services from the underlying container model that is used to house them.

So no matter what container you use, i.e. Castle Windsor, Spring, StructureMap etc pulling anything from the container in code will always be the same and consistent across layers.

Martin Fowler explains it better than I can here: http://www.martinfowler.com/articles/injection.html

All you have to do is write an implementor for the Service Locator to use. You'll note all the famous ones on the site above have already been implemented. But of course these don't work on the CF, so what do we do?

Firstly, you need to download the source code for the CommonServiceLocator as the project needs to be modified slightly. Simply remove all references to the ActivationException.Desktop class as the constructors in that class are not supported on the CF. That is it! - for the service locator project. Now all that remains is the implementor. This depends on what container you are using. We have been using a container called CompactContainer written by Germán Schuager that works well (uses reflection as it supports true dependency injection).

CompactContainer can be downloaded from here: http://code.google.com/p/compactcontainer/ it is freely available under the Apache Licence.

In order to write an implementor for the CommonServiceLocator, all you need to do is write a class that derives from abstract class ServiceLocatorImplBase, then tell the service locator where the instance of the container is and a reference to itself. This class implements IServiceLocator too, so itself can be injected into classes - for whatever reason.

The class is really simple, it could look something like this, here we have named it CompactServiceLocator:

public class CompactServiceLocator : ServiceLocatorImplBase
{
private readonly IContainer _compactContainer;
private bool _disposed;
public CompactServiceLocator(IContainer compactContainer)
{
_compactContainer = compactContainer;
}


protected override object DoGetInstance(Type serviceType, string key)
{
object resolvedObject = null;

// Resolve using a key if we have a key
if (!key.IsNull())
{
resolvedObject = _compactContainer.Resolve(key);
}

// Resolve using type if the object has not been resolved
if(resolvedObject == null && !serviceType.IsNull())
{
resolvedObject = _compactContainer.Resolve(serviceType);
}

return resolvedObject;
}

protected override IEnumerable<object>
DoGetAllInstances(Type serviceType)
{
return _compactContainer.GetServices(serviceType);
}

private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_compactContainer.Dispose();
}
_disposed = true;
}
}

public override void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

}
So essentially the above code is fairly simple in that all it is doing is it allows the service locator to call your specific container method. i.e. the implementation of method DoGetInstance() calls the specific container method to get an instance from the container. In this case it is method Resolve(). It is just implementation specific code which will look different from container to container.

So now you have written an implementor to go along side the Castle Windsor etc adapters, how do you use it? Well first you have to tell the Service Locator the container instance it should use, then set a reference to the service locator interface that maps to itself, like so:
Container container = new Container();
ServiceLocator.SetLocatorProvider(() => new CompactServiceLocator(container));
container.AddComponentInstance<IServiceLocator>(ServiceLocator.Current);
Container in this case is the CompactContainer freely available as mentioned above.

Asking for services is done as follows:
ServiceLocator.Current.GetInstance<IFooBar>();
Where IFooBar is your registered interface on the container.

That is it - as easy as that. If anyone would like me to put together a complete solution demoing this, please let me know. I didn't do it as the code is all available on line apart from the CompactContainer ServiceLocator implementor.

Windows Mobile 6.5.3 Developer Toolkit Released

You may have noticed that the Windows Mobile 6.5.3 SDK was released two weeks ago for 1 day then pulled from MSDN. I don't think Microsoft has made a public announcement why this was, but it is back under a new name. The 6.5.3 Developer Toolkit was uploaded today and can be downloaded from here:

http://www.microsoft.com/downloads/details.aspx?FamilyID=c0213f68-2e01-4e5c-a8b2-35e081dcf1ca&displaylang=en

Of course be sure to change your target project type within Visual Studio to make use of the new emulators.

Tuesday, February 16, 2010

Windows Phone 7 Series Announced at MWC



You've probably heard by now that Microsoft has announced Windows Phone 7 Series to the community on 15 Feb at the Mobile World Congress conference in Barcelona by Steve Ballmer. The Microsoft official press release can be found here.

I have to say the platform looks awesome. It looks very Zune HD like which is partly to do with the fact that Joe Belfiore is on the design team.

The best publicly available video to date that shows the platform UX is over on channel9 here:
http://channel9.msdn.com/posts/LauraFoy/First-Look-Windows-Phone-7-Series-Hands-on-Demo/

Dev Story:
If you're expecting to hear about the developer story or anything to do with the application platform then you'll be disappointed. Microsoft has not made any thing public regarding tools, frameworks etc for the new wave of Windows Phone 7 Series products. Microsoft is gearing up to tell the community about the developer story at MIX in Las Vegas on March 15-17. For sessions on Windows Phone 7 Series at this event see here.

For developer story announcements keep an eye on Charlie Kindels' blog as he is responsible for the Windows Phone 7 Series application platform.

The Windows team blog has a post on the announcement here.

The Windows Phone twitter hashtag is: #wm7

In Seattle at Summit



So it's that time of year again, I'm at the MVP Summit 2010 this year and looking forward to it as there are many new and exciting technologies being released out of Redmond.

I will post the stuff I can here.

Friday, October 30, 2009

Writing designer friendly controls for Windows Mobile

One thing that you sometimes need when writing Visual Studio designer friendly controls for Windows Mobile, is knowing if your code is running in design time - which is essentially running on the desktop or not. You need to know this because if you are running on the desktop (design time) you don't want to call device specific dlls.

The following code can be used to determine this:
public static class DesignMode
{
private static byte _mode = 255;

public static bool IsTrue
{
get
{
if (_mode == 255)
_mode = AppDomain.CurrentDomain.FriendlyName.Contains("DefaultDomain")
? (byte)1 : (byte) 0;
return _mode == 1;
}
}
}
So essentially you can then code in your application:
if (DesignMode.IsTrue)
{
//don't call coredll.dll
}
else
{
//call coredll.dll
}

Thursday, September 24, 2009

Zune HD

Review by WMExperts on the new Zune HD, very cool indeed:

Thursday, June 18, 2009

TechNet UK Virtual Conference 2009

Another virtual conference will be taking place tomorrow (Friday 19th June) which is the TechNet UK Virtual Conference.

Please find more information here: http://technet.microsoft.com/en-gb/dd819085.aspx

Sunday, June 14, 2009

DbDataReader.DoesColumnExist

Have you ever wanted to code something like the following:
var dbCommand = Database.DbProviderFactory.CreateCommand();
dbCommand.CommandText = "select * from MyTable";
var reader = Database.ExecuteReader(dbCommand, null);
if (reader.Read())
{
if (reader.DoesColumnExist("mycolumn")
{
//Then we know its safe to select the column.
}
}
You're probably thinking, why would I want to do that? well if you're building a generic data handler library and you don't know what columns have been selected but you know the columns that could be selected then it is very useful as using the indexer to return the data for the specified column will throw an exception if it doesn't exist.

I thought this extension method solves this problem and would be useful for others:
public static class DbDataReaderExtensions
{
public static bool DoesColumnExist(this IDataReader reader, string column)
{
if (reader.IsNull()) throw new ArgumentNullException("reader");
if (string.IsNullOrEmpty(column)) throw new ArgumentNullException("column");

for (var i = 0; i < reader.FieldCount; i++)
{
if (reader.GetName(i).Equals(column))
return true;
}
return false;
}
}
It's relatively straight forward but saves you from writing the same piece of code over and over again.

The unit test class for this is as follows:
[TestClass]
public class DataReaderExtensionsTests
{
[TestMethod]
public void ThrowsIfNullReaderIsPassed()
{
const MockDbDataReader reader = null;
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist("foo"));
}

[TestMethod]
public void ThrowsIfNullColumnIsPassed()
{
var reader = new MockDbDataReader();
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist(null));
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist(string.Empty));
}

[TestMethod]
public void ValidExists()
{
var reader = new MockDbDataReader();
Assert.IsTrue(reader.DoesColumnExist("One"));
Assert.IsTrue(reader.DoesColumnExist("Two"));
Assert.IsTrue(reader.DoesColumnExist("Three"));
Assert.IsTrue(reader.DoesColumnExist("Four"));
Assert.IsTrue(reader.DoesColumnExist("Five"));
}

[TestMethod]
public void InvalidExists()
{
var reader = new MockDbDataReader();
Assert.IsFalse(reader.DoesColumnExist("foo"));
Assert.IsFalse(reader.DoesColumnExist("bar"));
}
}
You'll notice I have mocked the DbDataReader. Because there are mocking frameworks on the Compact Framework and probably will not be for some time (due to CF limitations) I have created a mocked class implementing the IDataReader interface. This mock class looks like the following:
public class MockDbDataReader : IDataReader
{
readonly Dictionary<int, string> getName = new Dictionary<int, string>();
public MockDbDataReader()
{
getName.Add(0, "One");
getName.Add(1, "Two");
getName.Add(2, "Three");
getName.Add(3, "Four");
getName.Add(4, "Five");
}

#region IDataReader Members

public void Close()
{
throw new NotImplementedException();
}

public int Depth
{
get { throw new NotImplementedException(); }
}

public DataTable GetSchemaTable()
{
throw new NotImplementedException();
}

public bool IsClosed
{
get { throw new NotImplementedException(); }
}

public bool NextResult()
{
throw new NotImplementedException();
}

public bool Read()
{
throw new NotImplementedException();
}

public int RecordsAffected
{
get { throw new NotImplementedException(); }
}

#endregion

#region IDisposable Members

public void Dispose()
{
throw new NotImplementedException();
}

#endregion

#region IDataRecord Members

public int FieldCount
{
get { return 5; }
}

public bool GetBoolean(int i)
{
throw new NotImplementedException();
}

public byte GetByte(int i)
{
throw new NotImplementedException();
}

public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}

public char GetChar(int i)
{
throw new NotImplementedException();
}

public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}

public IDataReader GetData(int i)
{
throw new NotImplementedException();
}

public string GetDataTypeName(int i)
{
throw new NotImplementedException();
}

public DateTime GetDateTime(int i)
{
throw new NotImplementedException();
}

public decimal GetDecimal(int i)
{
throw new NotImplementedException();
}

public double GetDouble(int i)
{
throw new NotImplementedException();
}

public Type GetFieldType(int i)
{
throw new NotImplementedException();
}

public float GetFloat(int i)
{
throw new NotImplementedException();
}

public Guid GetGuid(int i)
{
throw new NotImplementedException();
}

public short GetInt16(int i)
{
throw new NotImplementedException();
}

public int GetInt32(int i)
{
throw new NotImplementedException();
}

public long GetInt64(int i)
{
throw new NotImplementedException();
}

public string GetName(int i)
{
return getName.ContainsKey(i) ? getName[i] : string.Empty;
}

public int GetOrdinal(string name)
{
throw new NotImplementedException();
}

public string GetString(int i)
{
throw new NotImplementedException();
}

public object GetValue(int i)
{
throw new NotImplementedException();
}

public int GetValues(object[] values)
{
throw new NotImplementedException();
}

public bool IsDBNull(int i)
{
throw new NotImplementedException();
}

public object this[string name]
{
get { throw new NotImplementedException(); }
}

public object this[int i]
{
get { throw new NotImplementedException(); }
}

#endregion
}
All we have done is returned 5 for the FieldCount, then provided some data so when GetName() is called we return the relevant item in the dictionary to resemble a real data reader object.

We could have written an integration test but this is pointless as we know the DataReader class has been tested and works.

The unit test class above gives 100% code coverage.

Thursday, June 04, 2009

JP Morgan Chase & Co. Corporate Challenge



Hitachi Consulting (including me) is participating in the JP Morgan Chase & Co. Corporate Challenge which is a world wide fundraising event in most major cities throughout the world.

Hitachi Consulting's goal is to raise £1000 for the Down's Syndrome Association and the challenge is a 6.5km run around Battersea park in London on the 9th July 2009.

If you were feeling generious :) you can sponsor the us over at:

http://www.justgiving.com/hcukjpmorganchallenge2009

Saturday, May 23, 2009

Microsoft patterns & practices Summit 2009



Microsoft are hosting the patterns & practices Summit Oct 12th - 16th 2009 at the Microsoft Conference Centre on Microsoft Campus in Redmond, WA.

To learn more about this event, see here: http://msdn.microsoft.com/en-us/practices/dd578307.aspx

Saturday, May 09, 2009

Microsoft Architect Insight Conference May 8th 2009 Mobile Decks for download



As promised to the delegates at the recent Microsoft Architect Insight Conference held on 8th May 2009 at Microsoft London Victoria, I have uploaded the decks from my breakout which was presented with Dave Baker from the Developer and Platform Group at Microsoft and my interactive session for download.

The two decks were used in the sessions Extending the Enterprise through Mobile and Mobile Implementation Patterns. Please note: the interactive Mobile Implementation Patterns deck is very light and the session was very much a chalk and talk session. I opened it up for debate for just about anything mobile. This deck contains some information about Hitachi Consulting who we are, our clients we've worked with which may interest you.

Thanks to Dave for giving a great session and also thanks to all the delegates in the interactive who made it a good discussion session.

You can download the decks here.

Monday, April 13, 2009

Copying dependency files to the output directory when running unit tests with MSTest

A rather long title don't you think :) But have you ever wanted to write a unit test using Visual Studio Test Edition and MSTest to have a dependency on configuration files other than app.config to fulfill your test?

This post is mainly about test support for device testing but is the same for desktop testing too.

Now, most people use app.config as a configuration file in .NET for desktop applications. On devices, System.Configuration is not supported. So some device developers end up writing there own configuration reader by serializing the XML into an object. Alternatively they use the class from OpenNETCF SDF or they might parse the XML using LINQ to XML or plain old System.Xml.

Personally I tend to use the serialization option. My configuration files are not named app.config I tend to name them something more specific. You'll find Visual Studio or the test engine does not deploy any other file to the tests Output directory, even if you set properties Build Action to Content and Copy to Output Directory to Copy always. Running your test will fail if you have a dependency on the given configuration file as Visual Studio will not deploy the custom configuration file. It is highly likely most desktop developers have never seen this or unaware this limitation exists because most desktop devs use app.config. In most cases for desktop devs there is no problem.

So how do device guys get around this problem? You can use the same technique as the Mobile p&p team do with the DataAccess block which forms part of the recent Mobile Application Blocks drop: http://www.codeplex.com/Mobile. In one of there test projects they have a mock database dependency that is tested on the desktop but need a sample database to test against.
They set the Build Action to Embedded Resource then they use reflection to unpack it. You might think this is quite a bit of work, but they have a reusable class named TestResourceFile that belongs to the TestUtilities project. Using this class does all the unpacking for you.

The code to copy this dependency could look like the following (I've taken this from the p&p Mobile codebase):
private TestResourceFile CreateDbFile()
{
dbFile = new TestResourceFile(this, "MockDatastore.sdf");
connectionString = String.Format(connectionStringPattern, dbFile.Filename);
return dbFile;
}

[TestMethod]
public void ThrowsIfNullParameterNameIsPassed()
{
using (TestResourceFile file = CreateDbFile())
{
using (Database database = new SqlDatabase(connectionString))
{
Database service = new SqlDatabase(connectionString);
ExtendedAssert.Throws(
delegate { DbParameter param = service.CreateParameter(null, "Maria Anders"); });
}
}
}
But even still there is a better way to solve this problem and that is to use the DeploymentItemAttribute class. It's use is simple. The following code illustrates it use:
[DeploymentItem("Mobile.DataMapper.config")]
[TestClass]
public class DataContextFactoryTests
{
}
The above code will copy the file "Mobile.DataMapper.config" to the test output directory. You need to ensure to set the file properties Build Action to Content and Copy to Output Directory to Copy always.

I've got to say thanks to Chris Tacke for telling me about this attribute class.

Sunday, April 12, 2009

http://answers.microsoft.com

Microsoft has recently (last few months) announced and released a website for Windows Vista users to post questions here: http://answers.microsoft.com.

There is quite a large MVP presence there to answer your Windows Vista questions.

Friday, April 10, 2009

What type of applications can we build on Windows Mobile today - Part 3 of 10

This is part 3 of 10 of the getting started with Windows Mobile development series. For previous posts in this series please see here.

Today mobile development is getting easier. Many folks from the desktop can port there C# skills over and hit the ground running fairly quickly. The Compact Framework is maturing nicely. Development tools and emulators are getting more feature rich and more reliable.

The types of applications you can build today for Windows Mobile - with regards to managed code fall into the following groups:
  1. Microsoft .NET Compact Framework. This is a subset of the Microsoft .NET Frameworkdesigned specifically for mobile devices. Use this technology for mobile applications that must run on the device without guaranteed network connectivity.
  2. ASP.NET Mobile. This is a subset of ASP.NET, designed specifically for mobile devices. ASP.NET Mobile applications can be hosted on a normal ASP.NET server. Use this technology for mobile Web applications when you need to support a large number of mobile devices and browsers that can rely on a guaranteed network connection.

ASP.NET for Mobile no longer has designer support in Visual Studio 2008. You can simply use the desktop controls and they will render. Now with "6on6" which is IE 6 engine on Windows Mobile 6.1 this will make web development for mobile easier. You can test IE 6 with the recently released WM 6.1 emulators. I wrote a post on this here. One thing to bear in mind is of course screen size.

Most developers write .NET Compact Framework applications over ASP.NET for LOB (Line of Business applications) due to the smart client nature. Also the power of a .NET CF application allows the developer to do whatever he wants. You can access the camera the GPS chipset the radio or the phone. You can access Outlook, manipulate appointments or add/change a contact. You can access a Relational Database Management system such as SQL Server Compact to store your applications data then sync back to SQL Server desktop using Sync Services (Sync Framework). You can write very compelling UI using GDI or on later devices GDI+ for support such as gradient backgrounds and transparency. XNA sadly is not supported, however DirectX is but is limited and memory intensive.

The main power of using the .NET Compact Framework over any other technology is the fact that it is embedded and works great in smart client environments where connectivity is an issue.

ASP.NET is rarely used in my experience, one reason is due to the connectivity issues. Under ASP.NET, mobile devices require a constant connection with the server in order for this type of architecture to work. Web applications do not work well in enterprise solutions for mobile devices. They do work well for consumer applications but not mission critical ones.

You'll probably be thinking how do you architect an application for the .NET Compact Framework. Most developers adopt the Active record pattern for the business layer. This tends to work well as mobile applications tend not to be as complex as desktop applications. And now performance tends not to be so much of a problem as it once was. ORMs and Domain Driven Development with patterns such as the repository data access layer is not quite as good a story.

The only ORM that supports the CF and SQL CE to date is LLBLGen. I am in the process of building an ORM for the Compact Framework and intend on writing an MSDN article how I did it.

The CF 3.5 does support WCF as a consumer, ServiceHost is not supported. There are many binding and other limitations however. Usually the device will have its own domain that uses either a message protocol which can be completely bespoke over TCP or a service layer with standard DTOs via HTTP. Or in some cases Sync data directly using Sync Services or merge replication. Each application is different. Of course vanilla Web Services ASMX has been supported since CF 1.0.

Monday, April 06, 2009

Thursday, April 02, 2009

An example of the Plugin pattern on the Compact Framework

I have been talking about IoC containers on the Compact Framework lately and thought I'd show an example of implementing a simpler example of separating concerns. There is another common pattern to which IoC I believe was derived called the Plugin pattern.

The Plugin pattern is talked about by Martin Fowler in his Patterns Of Enterprise Application Architecture book (good book by the way). It is (in my opinion) a simpler solution to IoC but is a little more limited and doesn't usually involve a framework.

I involves using reflection and creating a factory to create a type usually specified in a configuration file using a common interface. This pattern promotes Aspect Oriented Programming.

As I am in the process of building a managed ORM for the Compact Framework, I decided to use the Plugin pattern for building the data context part of the API. I decided this because the Plugin is easy to implement and doesn't require any framework to implement. I wanted to keep the ORM as simple as possible while at the same time making the framework decoupled from the type of database desired.

As mentioned I am using this pattern for the data context part of my ORM and I have a configuration file used to specify the type of database. Doing this enables me to easily change my database without having to rewrite a vast majority of my application. I don't even need to recompile my app. I can simply change the config and re-run my app.

The configuration setting that specifies the database dialect looks like this:
<property name="datacontext" value="Mobile.DataMapper.Dialect.SqlServerCe35DataContext"/>
The SqlServerCe35DataContext looks like:
public class SqlServerCe35DataContext : DataContext
{
private SqlDatabase _database;
private readonly MsSqlCe35Dialect _dialect;

public SqlServerCe35DataContext()
{
_dialect = new MsSqlCe35Dialect();
}

internal override Database Database
{
get
{
if (_database == null) _database = new SqlDatabase(ConnectionString);
return _database;
}
}

internal override Dialect Dialect
{
get { return _dialect; }
}
}
The DataContext class contains the default implementation of SQL Server CE and is defined as an abstract class. It also implements the IDataContext interface which we use in our factory. This enables us to use the Plugin pattern successfully.

Part of the DataContext class looks like this:
public abstract class DataContext : IDataContext
{
private DbTransaction _transaction;
private string _connectionString;

public virtual void Commit()
{
if (_transaction.IsNull()) throw new InvalidOperationException("There is no transaction for this session.");
_transaction.Commit();
}

public virtual void BeginTransaction()
{
_transaction = Database.GetConnection().BeginTransaction();
}

public virtual void BeginTransaction(IsolationLevel isolationLevel)
{
_transaction = Database.GetConnection().BeginTransaction(isolationLevel);
}

internal abstract Database Database
{
get;
}

internal abstract Dialect Dialect
{
get;
}
}
I've omitted many memebers as it's not important what this class does. What is important is the implementation in order to implement this pattern for devices.

For those interested, this is based on the Mobile Client Software Factory. I will be publishing the source code to my ORM for Windows Mobile soon - once finished.

So as we saw, the DataContext is abstract and it contains an interface. Just so you can see, the interface looks like this:
public interface IDataContext : IDisposable
{
string ConnectionString { get; set; }

//Transaction management.
void Commit();
void Rollback();
bool IsInTransaction{ get;}
void BeginTransaction();
void BeginTransaction(IsolationLevel isolationLevel);

IList<TEntity> Read<TEntity>(QueryExpressionCollection queryExpressionCollection);
IList<TEntity> Read<TEntity>(QueryExpressionCollection
queryExpressionCollection, List<Func<ObjectProperty>> columnsInScope);
IList<TEntity> FindAll<TEntity>();
TEntity Read<TEntity>(object id);

int Delete<TEntity>(TEntity entity);
TEntity Save<TEntity>(TEntity entity);
string DatabaseName { get; set; }

}
As I said I omitted most of the above members from the DataContext class above for clarity as I want to focus on the architecture not implementation details for this post.

So now we have four things:

1. Configuration file that tells us what datacontext to use.
2. The datacontext implementation (SQL CE Server) to use.
3. The base datacontext class.
4. The datacontext implementation.

The only thing that is missing to put all this together so the consumer can just work with the interface (as the consumer doesn't care about where the data lives or how the data is retrieved) is the DataContextFactory.

The Factory is very simple. It looks like this:
public class DataContextFactory
{
private IDataContext _instance;

public DataContextFactory()
{
CreateInstance(null);
}

public DataContextFactory(IDataMapperConfiguration dataMapperConfiguration)
{
CreateInstance(dataMapperConfiguration);
}

private void CreateInstance(IDataMapperConfiguration dataMapperConfiguration)
{
if (dataMapperConfiguration == null)
dataMapperConfiguration = MapperFactory.CreateDataMapperConfiguration();
var dataContext = dataMapperConfiguration.DataContext;
var asm = Assembly.GetExecutingAssembly();
_instance = (IDataContext)asm.CreateInstance(dataContext.Value);
if (dataMapperConfiguration.HasConnectionString)
_instance.ConnectionString = dataMapperConfiguration.ConnectionString.Value;
}

public IDataContext GetDataContext
{
get
{
return _instance;
}
}
}
Notice how we have another dependency the IDataMapperConfiguration. There's no need to document this code but quite simply it's a serialized object of the XML posted earlier. We get two things from this XML file 1. The ConnectionString and 2. The concrete DataContext class that implements DataContext. Notice how we set the ConnectionString property after the type has been created. We do this because the CF only supports one Assembly.CreateInstance method that accepts the type to create.

So using this code from the consumer looks like this:
IDataContext context = new DataContextFactory().GetDataContext;
then the consumer can work with this interface as opposed to the implementation. The consumer knows nothing about the underlying database or storage. If you changed the database from Sql CE to SQLLite for example, it is a simple case of changing the configuration file, then re-running the app.

You could implement this architecture with the IoC framework and using dependency injection pattern but the current one developed by the p&p team at Microsoft doesn't have support for configuration files. This means you'd have to recompile your app anytime you change the DataContext implementor. Now, no doubt Microsoft will roll out another version that supports configuration files in the future as the ContainerModel is a fairly early drop.

So the benefit with this implementation is, it's really really easy to implement and doesn't require any framework. If the implementors existed in another assembly, you could easily change the DataContextFactory to use the LoadFrom method to load a given assembly.

Wednesday, April 01, 2009

Dependency injection using the ContainerModel on the Compact Framework

I mentioned a few weeks ago about the availability of an IoC framework for the Compact Framework here.

But a question related to this is how do you implement the dependency injection pattern with this IoC framework as IoC (Inversion of Control) and dependency injection go hand in hand with one another.

The most common way to implement dependency injection is via the constructor. Sadley this container doesn't work like Castle Windsor where Castle resolves dependencies for you automatically without you having to define then when registering the class. However the class still needs to be defined by an interface! With the device Container model you have to explicitly define your dependencies at registration. I'm ok with this as I'm happy to have a half decent container model for the Compact Framework.

So we have our CustomerRepository class that has a dependency on some Adapter (I just made this adapter up, it could do anything). The class looks like this:
public class CustomerRepository : Repository<Customer, int>, ICustomerRepository
{
private IAdapter _adapter;

public CustomerRepository(IAdapter adapter)
{
if (adapter.IsNull()) throw new ArgumentNullException("adapter");
_adapter = adapter;
}
}
Now, there are no methods in this class but the point is to show the dependency because later, we want to use the adapter class to do some... adapting.

So how do we set up the container to inject the adapter. Something like the following should do the trick:
using Microsoft.Practices.Mobile.ContainerModel;
var builder = new ContainerBuilder();
builder.Register<IAdapter>(adapter => new Adapter());
builder.Register<ICustomerRepository>(repository => new CustomerRepository(Resolve<IAdapter>()));
builder.Build(container);
Then from the consumer, we can code something like the following:
var customerRepository = ComponentContainer.Resolve<ICustomerRepository>();
We didn't have to declare our dependency, it was injected by the framework. We just resolved the adapter when we registered the repository. Of course you need to register this dependency with the framework first. You could use the concrete type here but this means if you change implementation details, you'd have to change the implementor in more than one place.

There we have it, dependency injection using an IoC container on the Compact Framework 3.5.