Latest Tweet:
  • Loading...

One of the big themes of PDC this year was Windows Azure and Microsoft’s cloud computing initiative. Live Services is one of the building blocks of Windows Azure, and includes a set of services known as Live Mesh. I did a blog post about Live Mesh back in April when it was first announced. With lots of enthusiasm I speculated about how this would enable us to build offline/desktop enabled Silverlight applications. During the second day keynote Scott Guthrie, coding hero and vice president at Microsoft, announced that;

...in a few minutes you will learn about how you can actually run Silverlight both inside the browser and now outside the browser…
Photo by DBegley - check out original on Flickr

This announcement immediately caused a lot of buzz in the Twitter-sphere. What made the announcement even more interesting is that a lot of people didn’t quite get what Scott was talking about, or if they even showed Silverlight running outside the browser at all. So what was the Silverlight out-of-browser story at PDC? After Scotts keynote Anthony Rose entered stage and demoed their BBC iPlayer. He didn’t explicitly say that this was the “Silverlight running on the desktop”-story, but what he was showing was the iPlayer implemented as a Mesh-Enabled Silverlight application running on the desktop!

Anthony Rose
Photo by DBegley - check out the original on Flickr

In this blog post I’m going to show how I Mesh-enabled the Dive Log application using the Live Framework. I will also try to cover some of the benefits of using Live Mesh as an application platform for web application.

Where do you start?

To build Mesh-Enabled Web Applications you need access to the Live Framework SDK and Tools. The SDK is currently only available in a private CTP, and to get access you need to apply for a token through the Microsoft Connect site. I don’t know how many people they will let in on the CTP, or how long the process of getting a token takes.

Once you have downloaded and installed the SDK you get a new project type called Live Framework, which comes in two flavors; “Mesh-enabled Web Application” and “Silverlight Mesh-enabled Web Application”. The difference is that the first one is for writing JavaScript and HTML based Mesh-applications, while the second is for Silverlight applications that use the Live Framework libraries.

Live Framework Project Type

After selecting the “Silverlight Mesh-enabled Web Application” template you get a new solution with two projects; a Silverlight 2 project and a Live Framework project. The Live Framework project has a reference to the Silverlight project, and contains a simple HTML and JavaScript file to embed the Silverlight application on the HTML page. The project also contains an icon for the application, and an XML manifest file describing the application. The Silverlight project has references to two new assemblies; Microsoft.LiveFX.Client and Microsoft.LiveFX.ResourceModel. These are the Live Framework libraries that give you a managed API for Live Services. All Live Services are based on open protocols and standards like HTTP, ATOM, FeedSync and RSS, so you could write applications without these libraries, in any language or platform you like, but Live Framework makes it allot easier by providing a nice abstraction layer on top of the web services.

Live Framework Project Structure

Mesh-enabling the Dive Log application

meshappsicon The first thing I did after creating a new Live Framework project was to remove the automatically generated Silverlight 2 project. Instead I included my existing Dive Log Silverlight project and referenced the Live Framework Silverlight assemblies.

The Dive Log application was originally written as a demo for my TechEd talks back in September. One of the things I wanted to demonstrate was how to use the Model-View-ViewModel pattern in a Silverlight application, and how this can make your application easier to design in Expression Blend. The way I did that is to use dependency injection to inject a mock-implementation of any external dependencies, like web service proxies, into the view model. That way the mock service can generate sample data when the code is being consumed in Expression Blend. When the application is running in the browser the real web service will be used.

The benefit of this design is that I can easily configure my inversion of control container to use different implementations of different application services. So to first run the Dive Log application inside Live Mesh I simply configured the IoC container to always use the mock implementation of the web service. That way I could deploy my application to Live Mesh without having to prepare my web services for cross domain access.

After TechEd I have extended the Dive Log application with new features like printing support and support for back- and forward navigation in the browser. These features depend on the ASP.NET AJAX client library to be available on the page hosting the application. For my Mesh-enabled Dive Log I can’t depend on these libraries to be present, and I guess they don’t make sense when the application is deployed on the desktop anyway. So to disable these features I simply made an empty implementation of the IPrintDives and IManageHistory interfaces and configured my IoC container to use these to handle browser history and printing.

IoC container configuration code (available in download)

Once the application was configured to use the mock web service, and to disable printing and history, I could simply hit F5 to build and deploy the application to Live Mesh. The Live Framework project template includes a build task that will connect and deploy the application to Live Mesh. Currently there is no local development environment for Mesh-enabled web applications, something that can be a little bit bothersome as you have to redeploy the application to Live Mesh every time you make a change.

Application beeing deployed to Live Mesh

Mapping the Dive Log against the Live Framework Resource Model

The next step of Mesh-enabling the Dive Log application is to use the Live Framework Resource Model as the data storage for logged dives. The original application uses a web service to store dives remotely. This diagram shows a high level overview of the Live Framework Resource model. The blue boxes indicate the main components the Dive Log application will use.

Live Framework Resource Model Diagram

As I mentioned earlier the web service is an external dependency that is injected into the View Model using an IoC container. A trick I’ve used on many projects is to extract an interface defining the methods and events used on the web service client class. I then use a partial class to implement this interface on the automatically generated web service client class. This enables me to implement multiple versions of the interface, for instance for design time data or unit testing. This design enables me implement a new service that reads and writes dives to the Live Framework Resource Model. A simple configuration change of the IoC container will inject the Live Framework based service to the View Model. That way I don’t have to change any code in the UI or the View Model to use Live Mesh as my data storage.

IDiveLogServiceClient Diagram

The next challenge I faced was figuring out how to map my Dive Log application against the different concepts of the Live Framework Resource Model. After reading about the resource model my initial idea was to create one Mesh Object for each Dive Log, and then start adding items to a Data Feed. When I tried to create a new Mesh Object from my Silverlight application I got some weird exceptions. After discussion this on the Live Framework forum I learned that Mesh-enabled web applications don’t have permission to create new Mesh Objects. After some more trail-and-error, as well as watching sessions Live Framework sessions from PDC I came up with the following mapping of Dive Log concepts against the Live Framework Resource Model:

Dive Log to Live Framework Resource Model Mapping Diagram

The Mesh Object is the level of granularity for sharing, synchronization and authorization. In fact each instance of a Mesh-enabled web application is in itself a Mesh Object. This means that each Mesh-enabled web application got access to a single Mesh Object; the object representing the application instance. This enables you to share application instances with other users, and the Live Framework Client will synchronize the Mesh Object (application instance) across your devices. If you want to create two dive logs, one for hobby dives and one for professional dives, you simply create two application instances. This would create two Mesh Objects, one for each instance, which you could shared with other users and synchronize across devices. The following diagram illustrates the application sharing model. Each instance is a Mesh Object shared with another user, and both the application and its data get synchronized between users.

Live Framework Application Sharing Model

Coding against the Live Framework Resource Model

After working out how to map the Dive Log against the Live Framework Resource Model the next step was to write the actual implementation of the storage service. This was fairly straight forward as the Live Framework provides a nice API to work with the Live Services. In fact the complete implementation of the Live Framework backed storage service was less than 200 lines of code. One of the changes I had to make to my Dive-object was to add a new Mesh ID so that I could map Dive-objects against Sync Entry objects. When the user clicks the save button the code will create a new Sync Entry object and set the Dive-object as the user data. This enables you to serialize custom objects into a Mesh Sync/Data Entry. Both Sync- and Data Entries hang of a Data Feed. The main difference is that Sync Entries is the implementation of the Feed Sync standard. This helps you deal with synchronization of data across devices. This is helpful since multiple users could be writing data to the same application instance, some who might be offline and only synchronize data back into the cloud at a later stage.

The following piece of code shows the implementation of the save method. The code will iterate over each dive being saved and check if it has been changed. If the object is changed the code will see if it can find a Sync Entry matching the Dive. If it finds a Sync Entry it will update the object by calling SetUserData. If no Sync Entry can be found a new one is created and the dive object is stored by calling SetUserData on the new Sync Entry. Finally the Synchronize method is called on the Data Feed. This will push any changes made locally back into the cloud, as well as read any new objects added remotely by other users/devices.

Synchronizing dives back to Live Mesh

Benefits from Mesh-enabling the Dive Log application

Mesh-enabled web applications are a new type of applications. They are developed using web techniques like HTML, CSS, JavaScript or Silverlight, but can be deployed to the Live Mesh, and executed both inside the browser and on the desktop. This new application model opens up several new scenarios, and I think the Dive Log is a good example of an application that can benefit from being Mesh-enabled.

Screenshot of Dive Log Mesh on desktop

  • No need for server infrastructure
    As an application developer I can release the Dive Log application to the world without having to worry about server infrastructure. The application is deployed to Live Mesh, and all data is stored in the cloud. The user is in control of its own data and, and all dives are stored in an open ATOM based format that can be read by other applications.
  • Don’t have to worry about authentication and authorization
    I don’t have to worry about authentication, user management and authorization. All this is handled by Live Mesh and the Live Framework. The user authenticates using their Live ID, and authorization is managed by setting permissions on the Mesh-enabled application.
  • Transparent offline and online support
    My Dive Log application can work both offline and online. This is a big deal as a user might be interested in logging dives on his laptop onboard a boat far at sea. This would be hard to do in traditional web applications. With Mesh-enabled web applications the application is synchronized to the laptop, and any data added offline will be synchronized back into the cloud when a connection is available. The best thing is that you as an application developer don’t have to worry about it. The Live Framework client libraries will detect if the user is offline or online, and use the correct service endpoint (remote or local).
  • Making the Dive Log application social
    By Mesh-enabling the Dive Log application I get access to a big social network. Users can share their Dive Logs with friends, invite other users to use the application, and share news stories as the log new dives.

These are just some of the benefits from Mesh-enabling the Dive Log application. I think Live Mesh and Live Services are going to be an interesting application platform to watch as it matures. Currently the benefits for consumer based applications are obvious. It will be interesting to see if this platform can provide value for more business focused applications.

Download the Mesh-enabled Dive Log application

I have uploaded the source code of the Mesh-enabled Dive Log application. It is a simple Silverlight 2 application without the Live Framework project. You need to download and install the Live Framework SDK separately and then create a new Mesh-enabled Silverlight Project. Follow the steps described earlier in this post and add the Dive Log Silverlight application to your Live Framework project.

I have also published the Dive Log application to Live Mesh if you just want to run it as an end-user. You need to use the Live Mesh Tech Preview online environment, as well as download the Live Mesh Tech Preview client (if you want to run the application from your desktop and not only inside the browser).

<February 2010>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213